' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.

Imports System.ComponentModel

Namespace Microsoft.VisualBasic.ApplicationServices

    ''' <summary>
    '''  Abstract class that defines the application Startup/Shutdown model for VB
    '''  Windows Applications such as console, winforms, dll, service.
    ''' </summary>
    Public Class ConsoleApplicationBase : Inherits ApplicationBase

        ' Lazy-initialized and cached collection of command line arguments.
        Private _commandLineArgs As ObjectModel.ReadOnlyCollection(Of String)

        ''' <summary>
        '''  Constructs the application Shutdown/Startup model object
        ''' </summary>
        ''' <remarks>
        '''  We have to have a parameterless constructor because the platform
        '''  specific Application object derives from this one and it doesn't define
        '''  a constructor. The partial class generated by the designer defines
        '''  the constructor in order to configure the application.
        ''' </remarks>
        Public Sub New()
            MyBase.New()
        End Sub

        ''' <summary>
        '''  Allows derived classes to set what the command line should look like.
        '''  <see cref="WindowsFormsApplicationBase"/> calls this for instance
        '''  because we snag the command line from Main().
        ''' </summary>
        <EditorBrowsable(EditorBrowsableState.Advanced)>
        Protected WriteOnly Property InternalCommandLine() As ObjectModel.ReadOnlyCollection(Of String)
            Set(value As ObjectModel.ReadOnlyCollection(Of String))
                _commandLineArgs = value
            End Set
        End Property

        ''' <summary>
        '''  Returns the command line arguments for the current application.
        ''' </summary>
        ''' <remarks>
        '''  This function differs from <see cref="Environment.GetCommandLineArgs"/>
        '''  in that the path of the executing file (the 0th entry) is omitted from
        '''  the returned collection
        ''' </remarks>
        Public ReadOnly Property CommandLineArgs() As ObjectModel.ReadOnlyCollection(Of String)
            Get
                If _commandLineArgs Is Nothing Then
                    'Get rid of Arg(0) which is the path of the executing program. Main(args() as string) doesn't report the name of the app and neither will we
                    Dim envArgs As String() = Environment.GetCommandLineArgs
                    If envArgs.GetLength(0) >= 2 Then '1 element means no args, just the executing program. >= 2 means executing program + one or more command line arguments
                        Dim newArgs(envArgs.GetLength(0) - 2) As String 'dimming z(0) gives a z() of 1 element.
                        Array.Copy(envArgs, 1, newArgs, 0, envArgs.GetLength(0) - 1) 'copy everything but the 0th element (the path of the executing program)
                        _commandLineArgs = New ObjectModel.ReadOnlyCollection(Of String)(newArgs)
                    Else
                        _commandLineArgs = New ObjectModel.ReadOnlyCollection(Of String)(Array.Empty(Of String)())  'provide the empty set
                    End If
                End If
                Return _commandLineArgs
            End Get
        End Property

    End Class
End Namespace
