Imports System
Imports Plumtree.Remote.PRC

Imports Plumtree.Remote.PRC.Collaboration
Imports Plumtree.Remote.PRC.Collaboration.Project
Imports System.Collections
Imports System.Text



Namespace TestProject


    'Simple command line example which demonstrates creating a project,
    ' searching for a project, removing a project, and setting some project properties

    Public Class ProjectCommandLineExample

        'constants for endpoint, username, password and other command line args
        Shared ReadOnly ENDPOINT As String = "-endpoint"
        Shared ReadOnly USERNAME As String = "-username"
        Shared ReadOnly PASSWORD As String = "-password"
        Shared ReadOnly PROJECT_NAME As String = "-n"
        Shared ReadOnly PROJECT_DESCRIPTION As String = "-d"
        Shared ReadOnly PROJECT_ID As String = "-id"
        Shared ReadOnly CREATE As String = "-c"
        Shared ReadOnly REMOVE As String = "-r"
        Shared ReadOnly SEARCH As String = "-s"
        Shared ReadOnly SEARCH_QUERY As String = "-q"


        Shared Sub Main(ByVal args() As String)

            'make the arguments into a hashtable
            Dim argsMap As Hashtable = parseParameters(args)

            'get a remote session Imports the soap endpoint, username, and password
            Dim endpointUri As System.Uri = CType(argsMap.Item(ENDPOINT), Uri)
            Dim usernameStr As String = CType(argsMap.Item(USERNAME), String)
            Dim passwordStr As String = CType(argsMap.Item(PASSWORD), String)
            Dim session As IRemoteSession = RemoteSessionFactory.GetExplicitLoginContext(endpointUri, usernameStr, passwordStr)

            'get a collab factory and a project manager
            Dim collabFactory As ICollaborationFactory = session.GetCollaborationFactory()
            Dim projectManager As IProjectManager = collabFactory.GetProjectManager()

            'create, remove, search as specified by the client.
            If (argsMap.ContainsKey(CREATE)) Then
                createProject(projectManager, argsMap)
                Return
            ElseIf (argsMap.ContainsKey(REMOVE)) Then
                'get the id- squawk if it does not exist
                Dim projectStr As String = CType(argsMap.Item(PROJECT_ID), String)
                Dim projectInteger As Integer = Int32.Parse(projectStr)
                If (projectInteger <= 0) Then

                    Console.WriteLine("Project cannot be removed without a project ID")
                    Return
                End If
                removeProject(projectManager, projectInteger)
                Return
            ElseIf (argsMap.ContainsKey(SEARCH)) Then
                Dim queryString As String = CType(argsMap.Item(SEARCH_QUERY), String)
                If (queryString Is Nothing) Then
                    queryString = ""
                End If
                searchProjects(projectManager, queryString)
            End If

        End Sub

        'creates a project
        Public Shared Sub createProject(ByVal projectManager As IProjectManager, ByVal argsMap As Hashtable)

            'see if we have a name and description
            Dim name As String = CType(argsMap.Item(PROJECT_NAME), String)
            'set to a default value if there is no name
            If name Is Nothing Then
                name = "ExampleProjectName"
            End If
            Dim description As String = CType(argsMap.Item(PROJECT_DESCRIPTION), String)
            If description Is Nothing Then
                description = "ExampleProjectDescription"
            End If

            'create the project
            Dim project As IProject = projectManager.CreateProject(name, description)

            'if you want to set additional properties, make sure that store() is called or the changes will not be persisted.
            'for example:

            'Project.SetStatus(ProjectStatus.NOT_STARTED)
            'Project.SetStartDate(New Date)

            'store the project to get the ID
            project.Store()

            Console.WriteLine("ID of newly created project is " & CStr(project.ID))
        End Sub

        'removes a project
        Public Shared Sub removeProject(ByVal projectManager As IProjectManager, ByVal projectID As Integer)
            'retrieve the project
            Dim project As IProject = projectManager.GetProject(projectID)
            'squawk if the project could not be retrieved
            If project Is Nothing Then

                Console.WriteLine("Unable to retrieve project with ID of " & projectID)
                Return
            End If
            'remove
            projectManager.RemoveProject(project)
            Console.WriteLine("Project with id of " & CStr(projectID) & " removed.")
        End Sub


        'search for projects and iterate through the names and ids
        Public Shared Sub searchProjects(ByVal projectManager As IProjectManager, ByVal searchQuery As String)
            Dim projectFilter As IProjectFilter = projectManager.CreateProjectFilter()

            'hard-code the max results to 10
            projectFilter.MaximumResults = 10

            'set the query
            projectFilter.NameSearchText = searchQuery

            'execute the search and print out the results
            Dim projects() As IProject = projectManager.QueryProjects(projectFilter)
            If (projects.Length > 0) Then
                Dim i As Integer
                For i = 0 To projects.Length - 1
                    Dim project As IProject = projects(i)
                    Console.WriteLine("Project name is " & project.Name & " and project ID is " & CStr(project.ID) & Chr(10))
                Next
            Else
                Console.WriteLine("No projects found using search query of " & searchQuery)
            End If


        End Sub

        'helper method to parse command line parameters
        Public Shared Function parseParameters(ByVal args() As String) As Hashtable
            Dim map As Hashtable = New Hashtable
            'make the args into a list for easier processing
            Dim argsList As ArrayList = New ArrayList
            Dim i As Integer
            For i = 0 To args.Length - 1
                argsList.Add(args(i))
            Next
            'put the args into the map
            getArg(map, argsList, ENDPOINT, "Endpoint not specified", True)
            getArg(map, argsList, USERNAME, "Username not specified", True)
            getArg(map, argsList, PASSWORD, "Password not specified", True)
            getArg(map, argsList, PASSWORD, "Password not specified", True)
            getArg(map, argsList, PROJECT_NAME, "", False)
            getArg(map, argsList, PROJECT_DESCRIPTION, "", False)
            getArg(map, argsList, PROJECT_ID, "", False)
            getArg(map, argsList, CREATE, "", False)
            getArg(map, argsList, REMOVE, "", False)
            getArg(map, argsList, SEARCH, "", False)
            getArg(map, argsList, SEARCH_QUERY, "", False)
            Return map
        End Function

        'helper method to get parameters
        Public Shared Sub getArg(ByVal map As Hashtable, ByVal argsList As ArrayList, ByVal arg As String, ByVal errorMessage As String, ByVal required As Boolean)
            'get the position of the argument

            Dim position As Integer = argsList.IndexOf(arg)

            'special case for create, remove, and search
            Dim value As Object = Nothing
            'if not found and required, squawk and quit
            If (position = -1) Then
                If (required) Then
                    errorUsage(errorMessage)
                End If
            Else

                If (arg.Equals(CREATE) Or arg.Equals(REMOVE) Or arg.Equals(SEARCH)) Then
                    value = "true"
                Else
                    'check for index out of bounds exceptions
                    If (position + 1 = argsList.Count) Then
                        If (required) Then
                            errorUsage("Unable to find corresponding argument for " & arg)
                        End If
                    End If
                    value = argsList(position + 1)
                End If
                'special case for endpoint and project id
                If (arg.Equals(ENDPOINT)) Then
                    value = New Uri(CType(value, String))

                ElseIf (arg.Equals(PROJECT_ID)) Then
                    value = CType(value, String)

                End If
                'only add things once
                If Not map.ContainsKey(arg) Then
                    map.Add(arg, value)
                End If
            End If

        End Sub

        'method to print out an error message, usage, and exit
        Public Shared Sub errorUsage(ByVal errorMessage As String)
            Console.WriteLine(errorMessage)
            Console.WriteLine(Chr(10))
            printUsage()
            Environment.Exit(2)
        End Sub

        'prints usage
        Public Shared Sub printUsage()

            Dim usage As StringBuilder = New StringBuilder
            usage.Append("Usage: java ProjectCommandLineExample " & Chr(10))
            usage.Append(ENDPOINT)
            usage.Append(" http:'myserver:8080/ptapi/services/QueryInterfaceAPI " & Chr(10))
            usage.Append(USERNAME)
            usage.Append(" administrator -password """"" & Chr(10))
            usage.Append("To create a project, add ")
            usage.Append(CREATE)
            usage.Append(Chr(10) & "to optionally add a name and description, add " & Chr(10))
            usage.Append(PROJECT_NAME)
            usage.Append(" project_name ")
            usage.Append(PROJECT_DESCRIPTION)
            usage.Append(" project_description." & Chr(10))
            usage.Append("to remove a project, type ")
            usage.Append(REMOVE)
            usage.Append(" as well as ")
            usage.Append(PROJECT_ID)
            usage.Append(" and the project ID" & Chr(10))
            usage.Append("to query for projects, type ")
            usage.Append(SEARCH)
            usage.Append(" and optionally add a search query using " & Chr(10))
            usage.Append(SEARCH_QUERY)
            usage.Append(" followed by the query." & Chr(10))

            Console.WriteLine(usage.ToString())
        End Sub


    End Class

End Namespace

