Imports System

Imports Plumtree.Remote.PRC

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

Imports System.Collections
Imports System.Text


' Command line example which demonstrates simple discussion functionality,
' such as creating a discussion, searching for a discussion, removing a discussion, 
' creating a post, creating a reply, searching for posts, and removing a post.


Public Class DiscussionCommandLineExample
    '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 discussionManager As IDiscussionManager

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

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

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

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

        'create and store a discussion
        Dim discussion As IDiscussion = CreateAndStoreDiscussion(project, "Sample Discussion", "Description for Sample Discussion")

        'create and store a discussion message
        Dim message As IDiscussionMessage = CreateAndStoreMessage(discussion, "Sample Message 1", "Description for Sample Message 1")

        'create and store a reply to the message created
        Dim reply As IDiscussionMessage = CreateAndStoreReply(message, "Sample Reply", "Description for Sample Reply")

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

        'search for all discussions in current project, should retrieve 1 discussion
        SearchDiscussions(project)

        'search for all messages in current discussion, should retrieve 2 messages
        'results will be sorted by CREATED_DATE in descending order
        SearchMessages(discussion)


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

        'remove the first message from its containing discussion
        RemoveMessage(discussion, message)

        'remove the specified discussion
        RemoveDiscussion(discussion)

    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 discussion
    Public Shared Function CreateAndStoreDiscussion(ByVal project As IProject, ByVal name As String, ByVal description As String) As IDiscussion
        Dim discussion As IDiscussion = discussionManager.CreateDiscussion(project, name, description)

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

    'creates a discussion message
    Public Shared Function CreateAndStoreMessage(ByVal discussion As IDiscussion, ByVal name As String, ByVal description As String) As IDiscussionMessage
        'create the discussion message
        Dim message As IDiscussionMessage = discussion.CreateDiscussionMessage(name, description)

        ' if you want to set additional properties, make sure that store() is called or the changes will not be persisted
        message.Approved = True
        message.Description = "Option description for discussion message"

        'store the message to get the ID
        message.Store()
        Console.WriteLine(Chr(10) + "Created message has subject=" + message.Subject + ", body=" + message.Body + ", ID=" + CStr(message.ID) + ", description=" + message.Description)
        Return message
    End Function
    'creates a reply
    Public Shared Function CreateAndStoreReply(ByVal parentMessage As IDiscussionMessage, ByVal subject As String, ByVal body As String) As IDiscussionMessage
        'create the reply  createDiscussionReplyMessage() will create a persisted message, so
        'store() does not need to be called to persist the reply message properties unless additional properties are set.
        Dim reply As IDiscussionMessage = parentMessage.CreateDiscussionReplyMessage(subject, body)

        ' if you want to set additional properties, make sure that store() is called or the changes will not be persisted.
        reply.Description = "Optional description for reply message."
        reply.Approved = True

        'store the reply message to get the ID
        reply.Store()
        Console.WriteLine(Chr(10) + "Created reply message has subject=" + reply.Subject + ", body=" + reply.Body + ", ID=" + CStr(reply.ID) + ", description=" + reply.Description)
        Return reply
    End Function

    'queries discussions in a project
    Public Shared Function SearchDiscussions(ByVal project As IProject) As IDiscussion()
        Dim discussionFilter As IDiscussionFilter = discussionManager.CreateDiscussionFilter()

        'search for all discussions

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

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

        'an array of IDiscussion are returned from queryDiscussions()  if no result is retrieved, a zero-length array will be returned
        Dim retrievedDiscussions As IDiscussion() = discussionManager.QueryDiscussions(project, discussionFilter)

        Console.WriteLine(Chr(10) + "Searching for discussion in project with name=" + project.Name + " gets back " + CStr(retrievedDiscussions.Length) + " results.")
        Dim i As Integer
        For i = 0 To retrievedDiscussions.Length - 1
            Dim retrievedDiscussion As IDiscussion = retrievedDiscussions(i)
            Console.WriteLine("Retrieved discussion(" + CStr(i) + ") has name=" + retrievedDiscussion.Name + ", ID=" + CStr(retrievedDiscussion.ID))
        Next
        Return retrievedDiscussions
    End Function
    'queries messages in a discussion
    Public Shared Function SearchMessages(ByVal discussion As IDiscussion) As IDiscussionMessage()
        Dim messageFilter As IDiscussionMessageFilter = discussionManager.CreateDiscussionMessageFilter()

        'search for ALL messages  other options include searching for APPROVED, or UNAPPROVED messages
        messageFilter.MessageStatusType = DiscussionMessageStatusFilterTypes.All

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

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

        'user DiscussionMessageQueryOrder to sort the query result  below DiscussionMessageQueryOrder
        'shows sorting the returned messages by CREATED date in descending order
        Dim messageQueryOrder As DiscussionMessageQueryOrder = New DiscussionMessageQueryOrder(DiscussionMessageAttributes.Created, False)
        Dim messageQueryOrders(0) As DiscussionMessageQueryOrder
        messageQueryOrders(0) = messageQueryOrder
        messageFilter.QueryOrders = messageQueryOrders

        'an array of IDiscussionMessage objects are returned from queryDiscussionMessages()  if no result is retrieved, a zero-length array will be returned
        Dim retrievedMessages() As IDiscussionMessage = discussionManager.QueryDiscussionMessages(discussion, messageFilter)

        Console.WriteLine(Chr(10) + "Searching for messages in discussion with name=" + discussion.Name + ", and DiscussionMessageStatusFilterType set to " + CStr(DiscussionMessageStatusFilterTypes.All) + " gets back " + CStr(retrievedMessages.Length) + " results.")
        Dim i As Integer
        For i = 0 To i < retrievedMessages.Length - 1
            Console.WriteLine("Retrieved messages[" + CStr(i) + "] has subject=" + retrievedMessages(i).Subject + ", ID=" + CStr(retrievedMessages(i).ID))
        Next
        Return retrievedMessages
    End Function

    'removes a discussion
    Public Shared Sub RemoveDiscussion(ByVal discussion As IDiscussion)
        Dim discussionID As Integer = discussion.ID
        Console.WriteLine(Chr(10) + "Trying to remove discussion with name=" + discussion.Name + ", ID=" + CStr(discussionID))
        discussionManager.RemoveDiscussion(discussion)

        'trying to retrieve the discussion after removal, should retrieve nothing
        Dim discussionAfterRemoval As IDiscussion = discussionManager.GetDiscussion(discussionID)
        If discussionAfterRemoval Is Nothing Then
            Console.WriteLine("Discussion successfully removed.")
        Else
            Console.WriteLine("Failed to remove discussion.")
        End If
    End Sub
    'removes a message a discussion
    Public Shared Sub RemoveMessage(ByVal discussion As IDiscussion, ByVal message As IDiscussionMessage)
        Dim messageID As Integer = message.ID
        Console.WriteLine(Chr(10) + "Trying to remove message with subject=" + message.Subject + ", ID=" + CStr(messageID))
        discussion.RemoveDiscussionMessage(message)

        'trying to retrieve the message after removal, should retrieve nothing
        Dim messageAfterRemoval As IDiscussionMessage = discussionManager.GetDiscussionMessage(messageID)
        If messageAfterRemoval Is Nothing Then

            Console.WriteLine("Message successfully removed.")
        Else
            Console.WriteLine("Failed to remove message.")
        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")
        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: DiscussionCommandLineExample " + Chr(10))
        usage.Append(ENDPOINT)
        usage.Append(" http:'myserver:8080/ptapi/services/QueryInterfaceAPI " + Chr(10))
        usage.Append(USERNAME)
        usage.Append(" administrator -password """"" + Chr(10))

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