Imports System

'import IRemoteSession explicitly to aSubd naming conflicts
Imports Plumtree.Remote.PRC

Imports Plumtree.Remote.PRC.Collaboration.Project
Imports Plumtree.Remote.PRC.Collaboration.Tasklist
Imports RemoteSessionFactory = Plumtree.Remote.PRC.RemoteSessionFactory
Imports Plumtree.Remote.PRC.Collaboration

Imports System.Collections
Imports System.Text


' Simple command line example which demonstrates simple task list functionality, such as
' creating a task list, searching for a task list, removing a task list.

Public Class TaskListCommandLineExample
    'constants for endpoint, username, password and other command line args
    Public Shared ReadOnly ENDPOINT As String = "-endpoint"
    Public Shared ReadOnly USERNAME As String = "-username"
    Public Shared ReadOnly PASSWORD As String = "-password"

    Private Shared projectManager As IProjectManager
    Private Shared tasklistManager As ITaskListManager

    Public 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 remoteSession As IRemoteSession = RemoteSessionFactory.GetExplicitLoginContext(endpointUri, usernameStr, passwordStr)

        'get a collab factory and a project manager
        Dim collabFactory As ICollaborationFactory = remoteSession.GetCollaborationFactory()
        projectManager = collabFactory.GetProjectManager()
        tasklistManager = collabFactory.GetTaskListManager()


        ' ----- CREATE functionality ----- 

        'create and store the containing project
        Dim project As IProject = CreateAndStoreProject("Sample Project", "Description for Sample Project")

        'create and store a task list
        Dim tasklist As ITaskList = CreateAndStoreTaskList(project, "Sample TaskList", "Description for Sample TaskList")

        'create and store a top-level task, with startTime set to 9/1/2004, endTime set to 9/8/2004
        Dim toplevelTask As ITask = CreateAndStoreTopLevelTask(tasklist, "Sample TopLevel Task 1", "Description for Sample TopLevel Task 1", New DateTime(2004, 9, 1), New DateTime(2004, 9, 8))

        'create and store a sub-task, with startTime set to 9/2/2004, endTime set to 9/4/2004
        Dim subTask As ITask = CreateAndStoreSubTask(toplevelTask, "Sample Sub Task", "Description for Sample Sub Task", New DateTime(2004, 9, 2), New DateTime(2004, 9, 4))

        'create and store another toplevel task, which is going to be added as a dependent task of subTask 
        Dim dependentTask As ITask = CreateAndStoreDependentTask(tasklist, "Dependent Task", "Task that depends on Toplevel Task 1", New DateTime(2004, 9, 8), New DateTime(2004, 9, 10), subTask)


        ' ----- SEARCH functionality -----

        'search for all task lists in current project, should retrieve 1 task list
        SearchTaskLists(project)

        'search for all tasks in current task list, should retrieve 3 tasks
        'results will be sorted by NAME in ascending order
        SearchTasks(tasklist)

        ' ----- COPY functionality -----

        'create a target project for copying task lists from source project 
        Dim targetProject As IProject = CreateAndStoreProject("Target Project for Copy", "Description for target Project")
        Dim taskLists(0) As ITaskList
        taskLists(0) = tasklist
        CopyTaskLists(project, targetProject, taskLists)

        ' ----- REMOVE functionality -----

        'remove the toplevelTask from its containing task list
        removeTask(tasklist, toplevelTask)

        'remove the specified task list
        removeTasklist(tasklist)

    End Sub

    'creates a project - please see Project Example for detailed documentation
    Public Shared Function CreateAndStoreProject(ByVal name As String, ByVal description As String) As IProject
        Dim project As IProject = projectManager.CreateProject(name, description)
        project.Store()
        Return project
    End Function

    'creates a task list
    Public Shared Function CreateAndStoreTaskList(ByVal project As IProject, ByVal name As String, ByVal description As String) As ITaskList
        Dim tasklist As ITaskList = tasklistManager.CreateTaskList(project, name, description)

        'store the task list to get the ID
        tasklist.Store()
        Console.WriteLine(Chr(10) + "Created task list has name=" + tasklist.Name + ", ID=" + CStr(tasklist.ID))
        Return tasklist
    End Function


    'creates a task
    Public Shared Function CreateAndStoreTopLevelTask(ByVal tasklist As ITaskList, ByVal name As String, ByVal description As String, ByVal startTime As DateTime, ByVal endTime As DateTime) As ITask
        'create the task
        Dim task As ITask = tasklist.CreateTask(name, description, startTime, endTime)

        ' if you want to set additional properties, make sure that store() is 
        ' called or the changes will not be persisted.
        task.Notes = "Notes for sample TopLevel Task"
        task.Risk = TaskRisks.Medium
        task.Status = TaskStatuses.Pending

        'store the task to get the ID
        task.Store()
        Console.WriteLine(Chr(10) + "Created top-level task has name=" + task.Name + ", ID=" + CStr(task.ID) + ", risk=" + CStr(task.Risk) + ", status=" + CStr(task.Status) + ", and notes=" + task.Notes)
        Return task
    End Function
    'creates a subtask
    Public Shared Function CreateAndStoreSubTask(ByVal parentTask As ITask, ByVal name As String, ByVal description As String, ByVal startTime As DateTime, ByVal endTime As DateTime) As ITask
        'create the subtask  createSubTask() will create a persisted task, so
        ' store() does not need to be called to persist the task properties unless additional properties are set.
        Dim subtask As ITask = parentTask.CreateSubTask(name, description, startTime, endTime)

        ' if you want to set additional properties, make sure that store() is 
        ' called or the changes will not be persisted.
        subtask.Risk = TaskRisks.Low
        subtask.Status = TaskStatuses.FiftyPercentCompleted

        'store the subtask to get the ID
        subtask.Store()
        Console.WriteLine(Chr(10) + "Created sub-task has name=" + subtask.Name + ", ID=" + CStr(subtask.ID) + ", and parentTask=" + subtask.GetParentTask().Name)
        Return subtask
    End Function
    'creates a task, and then add the source task as its dependency
    Public Shared Function CreateAndStoreDependentTask(ByVal tasklist As ITaskList, ByVal name As String, ByVal description As String, ByVal startTime As DateTime, ByVal endTime As DateTime, ByVal sourceTask As ITask) As ITask
        'create a toplevel task first
        Dim dependentTask As ITask = tasklist.CreateTask(name, description, startTime, endTime)

        'add the sourceTask as the current task's dependency, make sure that store() is 
        'called after addDependentTask(), similar to the other task properties,
        'otherwise the newly-added dependency will not be persisted.
        dependentTask.AddDependentTask(sourceTask)

        'store the task to persist the added dependency and get the ID
        dependentTask.Store()

        'Notice that upon adding a dependent task, the start time of the task will be set automatically to 
        'the end time of dependent source task.

        'retrieve all source tasks that this tasks depends on
        Dim taskDependency() As ITask = dependentTask.GetTaskDependencies()
        Dim taskDependencyName As String = taskDependency(0).Name

        Console.WriteLine(Chr(10) + "Created task has name=" + dependentTask.Name + ", ID=" + CStr(dependentTask.ID) + ", which has a dependency on sourceTask=" + taskDependencyName)
        Return dependentTask
    End Function

    'queries task lists in a project
    Public Shared Function SearchTaskLists(ByVal project As IProject) As ITaskList()
        Dim taskListFilter As ITaskListFilter = tasklistManager.CreateTaskListFilter()

        'set the query to search for all task list
        ' different options can be set to search on task lists that contain only PENDING tasks, 
        ' completed tasks, or overdue tasks.  See documentation in TaskListCompletionFilterType
        taskListFilter.CompletionType = TaskListCompletionFilterTypes.All

        'limit the return results to be 10  setting this to 0 will return all results
        taskListFilter.MaximumResults = 10

        'disable security checking on the returned objects against the user who performs this query, 
        'so that all objects will be returned
        taskListFilter.RestoreSecurity = False

        'user TaskListQueryOrder to sort the query result  below TaskListQueryOrder shows sorting the returned task lists by NAME in ascending order
        Dim taskListQueryOrder As TaskListQueryOrder = New TaskListQueryOrder(TaskListAttributes.Name, True)
        Dim taskListQueryOrders(0) As TaskListQueryOrder
        taskListQueryOrders(0) = taskListQueryOrder
        taskListFilter.QueryOrders = taskListQueryOrders

        'an array of ITaskList objects are returned from queryTaskLists()  if no result is retrieved, a zero-length array will be returned
        Dim retrievedTaskLists() As ITaskList = tasklistManager.QueryTaskLists(project, taskListFilter)

        Console.WriteLine(Chr(10) + "Searching for task list in project with name=" + project.Name + ", and TaskListCompletionFilterTypes set to " + CStr(TaskListCompletionFilterTypes.All) + " gets back " + CStr(retrievedTaskLists.Length) + " results.")
        Dim i As Integer
        For i = 0 To retrievedTaskLists.Length - 1
            Console.WriteLine("Retrieved task list[" + CStr(i) + "] has name=" + retrievedTaskLists(i).Name + ", ID=" + CStr(retrievedTaskLists(i).ID))
        Next
        Return retrievedTaskLists
    End Function
    'queries tasks in a task list
    Public Shared Function SearchTasks(ByVal tasklist As ITaskList) As ITask()
        Dim taskFilter As ITaskFilter = tasklistManager.CreateTaskFilter()

        'search on all tasks  other options include searching for COMPLETED tasks, OVERDUE tasks, or PENDING tasks
        taskFilter.CompletionType = TaskCompletionFilterTypes.All

        'limit the return results to be 10  setting this to 0 will return all results
        taskFilter.MaximumResults = 10

        'disable security checking on the returned objects against the user who performs this query, 
        'so that all objects will be returned
        taskFilter.RestoreSecurity = False

        'user TaskQueryOrder to sort the query result  below TaskQueryOrder shows sorting the returned task lists by NAME in ascending order
        Dim tQueryOrder As TaskQueryOrder = New TaskQueryOrder(TaskAttributes.Name, True)
        Dim taskQueryOrders(0) As TaskQueryOrder
        taskQueryOrders(0) = tQueryOrder
        taskFilter.QueryOrders = taskQueryOrders

        'an array of ITask objects are returned from queryTasks(ITaskList)  if no result is retrieved, a zero-length array will be returned
        Dim retrievedTasks() As ITask = tasklistManager.QueryTasks(tasklist, taskFilter)

        Console.WriteLine(Chr(10) + "Searching for tasks in task list with name=" + tasklist.Name + ", and TaskListCompletionFilterTypes set to " + CStr(TaskListCompletionFilterTypes.All) + " gets back " + CStr(retrievedTasks.Length) + " results.")
        Dim i As Integer
        For i = 0 To retrievedTasks.Length - 1
            Console.WriteLine("Retrieved task[" + CStr(i) + "] has name=" + retrievedTasks(i).Name + ", ID=" + CStr(retrievedTasks(i).ID))
        Next
        Return retrievedTasks
    End Function

    'removes a task list
    Public Shared Sub removeTasklist(ByVal tasklist As ITaskList)
        Dim tasklistID As Integer = tasklist.ID
        Console.WriteLine(Chr(10) + "Trying to remove task list with name=" + tasklist.Name + ", ID=" + CStr(tasklistID))
        tasklistManager.RemoveTaskList(tasklist)

        ' trying to retrieve the task list after removal, should retrieve nothing
        Dim taskListAfterRemoval As ITaskList = tasklistManager.GetTaskList(tasklistID)
        If taskListAfterRemoval Is Nothing Then
            Console.WriteLine("Tasklist successfully removed.")
        Else
            Console.WriteLine("Failed to remove task list.")
        End If
    End Sub

    'removes a task a task list
    Public Shared Sub removeTask(ByVal tasklist As ITaskList, ByVal task As ITask)
        Dim taskID As Integer = task.ID
        Console.WriteLine(Chr(10) + "Trying to remove task with name=" + task.Name + ", ID=" + CStr(taskID))
        tasklist.RemoveTask(task)

        ' trying to retrieve the task after removal, should retrieve nothing
        Dim taskAfterRemoval As ITask = tasklistManager.GetTask(taskID)
        If taskAfterRemoval Is Nothing Then
            Console.WriteLine("Task successfully removed.")
        Else
            Console.WriteLine("Failed to remove task.")
        End If
    End Sub

    'copy content of a task list into another task list
    Public Shared Sub CopyTaskLists(ByVal sourceProject As IProject, ByVal targetProject As IProject, ByVal tasklistsToCopy() As ITaskList)
        Console.WriteLine(Chr(10) + "Trying to copy " + CStr(tasklistsToCopy.Length) + " task list(s) from source project.")

        'iterate through the task lists to copy from source project
        Dim i As Integer
        For i = 0 To tasklistsToCopy.Length - 1
            Console.WriteLine("Tasklist to copy [" + CStr(i) + "] has name=" + tasklistsToCopy(i).Name + ", ID=" + CStr(tasklistsToCopy(i).ID))
        Next
        tasklistManager.CopyTaskLists(sourceProject, targetProject, tasklistsToCopy)

        'check if the task lists are copied into the target project 
        Dim tasklistFilter As ITaskListFilter = tasklistManager.CreateTaskListFilter()

        Dim copiedTasklists() As ITaskList = tasklistManager.QueryTaskLists(targetProject, tasklistFilter)

        Console.WriteLine("Copied " + CStr(copiedTasklists.Length) + " task list(s) into target project.")

        'iterate through the task lists to copy from source project
        i = 0
        For i = 0 To copiedTasklists.Length - 1
            Console.WriteLine("Successfully copied task list [" + CStr(i) + "] has name=" + copiedTasklists(i).Name + ", ID=" + CStr(copiedTasklists(i).ID))
        Next
    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")
        GetArg(map, argsList, USERNAME, "Username not specified")
        GetArg(map, argsList, PASSWORD, "Password not specified")
        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)
        'get the position of the argument        
        Dim position As Integer = argsList.IndexOf(arg)

        'if not found and required, squawk and quit
        If (position = -1) Then
            ErrorUsage(errorMessage)
        Else
            'special case for create, remove, and search
            Dim value As Object = Nothing
            'check for index out of bounds exceptions
            If (position + 1 = argsList.Count) Then
                ErrorUsage("Unable to find corresponding argument for " + arg)
            End If
            value = argsList(position + 1)

            'special case for endpoint and project id
            If (arg.Equals(ENDPOINT)) Then
                value = New Uri(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(Chr(10) + "Usage: TaskListCommandLineExample " + Chr(10))
        usage.Append(ENDPOINT)
        usage.Append(" http:'myserver:8080/ptapi/services/QueryInterfaceAPI \n")
        usage.Append(USERNAME)
        usage.Append(" administrator -password """"" + Chr(10))

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

End Class
