using Plumtree.Remote.PRC.Collaboration.Project;
using Plumtree.Remote.PRC.Collaboration.Document;
using IRemoteSession = Plumtree.Remote.PRC.IRemoteSession;
using RemoteSessionFactory = Plumtree.Remote.PRC.RemoteSessionFactory;

using System;
using System.IO;

///<summary>
/// To change this example to run on any collaboration server, be sure to change the endpointURL, username and password
/// which are all set at the beginning of the Main method.
/// The example code also assumes that the files c:\report.doc and c:\report2.doc exist.  
/// Create these files or change the references below.
///</summary>
public class DocumentCommandLineExample
{
   static IDocumentManager documentManager;
   static IProjectManager projectManager;

   public static void Main(string[] args)
   {
       //Change the values below to match your configuration
       Uri endpointURL = new Uri("http://localhost:8080/ptapi/services/QueryInterfaceAPI");
       string username = "Administrator";
       string password = "";

       //Connect to create a session & retrieve the document manager
       IRemoteSession remoteSession = RemoteSessionFactory.GetExplicitLoginContext(endpointURL, username, password);
       documentManager = remoteSession.GetCollaborationFactory().GetDocumentManager();
       projectManager = remoteSession.GetCollaborationFactory().GetProjectManager();

       //Create a project to work in
       IProject exampleProject = projectManager.CreateProject("document example project", "example document project");
       //Store it
       exampleProject.Store();

       /*** Create new objects ***/
       //Create a new folder
       IDocumentFolder newFolder = CreateAndInsertNewFolder(exampleProject, "example folder");

       //Create a new document
       IDocument newDocument = CreateAndInsertNewDocument(newFolder);

       /*** Edit the document ***/
       //Check it out for editing
       documentManager.CheckOutDocument(newDocument);

       //We can query here, and get the checked out document
       IDocument[] checkedOutDocuments = FindCheckedOutDocumentsInProject(exampleProject);

       //Check in a new version
       CheckInNewDocumentVersion(newDocument);

       //Retrieve the content back, and store it to a file
       StoreDocumentContent(newDocument);

       //Create a another folder...
       IDocumentFolder newFolder2 = CreateAndInsertNewFolder(exampleProject, "example folder 2");

       //Then copy the new document to it
       CopyDocumentToFolder(newDocument, newFolder, newFolder2);

       //We can query here, and get the two created folders
       IDocumentFolder[] rootFolders = FindFirstLevelFolders(exampleProject);

       /*** Remove the objects ***/
       //Remove the document
       documentManager.RemoveDocument(newDocument);

       //Remove the folder
       documentManager.RemoveDocumentFolder(newFolder);

       //Remove the main project (which removes all contained objects)
       projectManager.RemoveProject(exampleProject);
   }

   public static IDocumentFolder[] FindFirstLevelFolders(IProject project)
   {
       //Create the new query filter
       IDocumentFolderFilter filter = documentManager.CreateDocumentFolderFilter();

       //Set to order by name
       DocumentFolderQueryOrder nameOrder = new DocumentFolderQueryOrder(DocumentFolderAttributes.Name, true);
       DocumentFolderQueryOrder[] orders = new DocumentFolderQueryOrder[]{nameOrder};
       filter.QueryOrders = orders;

       //To find folders in a project, we must look in the top level folder
       IDocumentFolder topLevelFolder = documentManager.GetTopLevelFolder(project);
       IDocumentFolder[] foundFolders = documentManager.QueryFolders(topLevelFolder, filter);

       return foundFolders;
   }

   public static IDocument[] FindCheckedOutDocumentsInProject(IProject project)
   {
       //Create the new query filter
       IDocumentFilter filter = documentManager.CreateDocumentFilter();

       //Set it to only search for checked-out documents
       filter.FilterType = DocumentFilterTypes.CheckedOutByCurrentUser;

       //Set to order by size, then last modified date
       DocumentQueryOrder sizeOrder = new DocumentQueryOrder(DocumentAttributes.NumBytes, true);
       DocumentQueryOrder lastModifiedOrder = new DocumentQueryOrder(DocumentAttributes.LastModified, true);
       DocumentQueryOrder[] orders = new DocumentQueryOrder[]{sizeOrder, lastModifiedOrder};
       filter.QueryOrders = orders;

       //Perform query
       IDocument[] foundDocuments = documentManager.QueryDocuments(project, filter);
       return foundDocuments;
   }

   public static void CopyDocumentToFolder(IDocument documentToCopy, IDocumentFolder sourceFolder, IDocumentFolder targetFolder)
   {
       //Documents to copy
       IDocument[] documentsToCopy = new IDocument[]{documentToCopy};

       //We won't copy any folders
       IDocumentFolder[] foldersToCopy = new IDocumentFolder[0];

       //Copy the document, inheriting the security from the target folder
       documentManager.CopyToFolder(sourceFolder, targetFolder, documentsToCopy,  foldersToCopy, true, "copied from original sample folder");
   }

   public static void CheckInNewDocumentVersion(IDocument originalDocument)
   {
       //Open an inputstream for the document contents
       FileStream fileInputStream = File.OpenRead("c:\\report2.doc");

       //Check in the new version
       documentManager.CheckInDocument(originalDocument, "this is an updated version of the example document", fileInputStream, "en", false);
   }

   public static IDocument CreateAndInsertNewDocument(IDocumentFolder containingFolder)
   {
       //Create the document
       IDocument newDocument = documentManager.CreateNewDocument("my new document", "this is a test document created by the samples");

       //Set optional properties
       newDocument.Author = "joe bloggs";

       //Set content-type
       newDocument.ContentType = "text/vnd.ms-word";

       //Open an inputstream for the document contents
       FileStream fileInputStream = File.OpenRead("c:\\report.doc");

       //Insert the document, inheriting the containing folder's security
       IDocument storedDocument = documentManager.InsertNewDocument(containingFolder, newDocument, "initial check-in", fileInputStream, "en", true);

       return storedDocument;
   }

   public static IDocumentFolder CreateAndInsertNewFolder(IProject containingProject, string name)
   {
       //Create the folder
       IDocumentFolder newFolder = documentManager.CreateNewFolder(name, "this is a test folder created by the examples");

       //Could now set optional properties such as security on newFolder before store...

       //Get the top level folder of the project to insert the document into
       IDocumentFolder topLevelFolder = documentManager.GetTopLevelFolder(containingProject);

       //Insert the folder, inheriting the top level folder's security
       IDocumentFolder storedFolder = documentManager.InsertNewFolder(topLevelFolder, newFolder, true);

       return storedFolder;
   }

   public static void StoreDocumentContent(IDocument toStore)
   {
       //Generate a file name to store the content to
       string nameToUse = toStore.Name + ".doc";

       //Create an output stream to store the data
       FileStream fileOutputStream = File.OpenWrite(nameToUse);

       Stream documentContentStream = null;

       try
       {
           //Get the content stream
           documentContentStream = toStore.GetContentAsInputStream();

           //Pump it out to a file
           byte[] buf = new byte[32 * 1024];
           int read = documentContentStream.Read(buf, 0, buf.Length);

           while(read > 0)
           {
               fileOutputStream.Write(buf, 0, read);
               read = documentContentStream.Read(buf, 0, buf.Length);
           }
       }
       finally //make sure the stream is closed
       {
           documentContentStream.Close();
           fileOutputStream.Close();
       }
   }
}
