﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
using System.Collections.Generic;
using DotCMIS;
using DotCMIS.Client;
using DotCMIS.Client.Impl;
using DotCMIS.Enums;
using NUnit.Framework;
using System;
using DotCMIS.Data;
using DotCMIS.Data.Impl;
using System.Text;
using System.IO;
using DotCMIS.Exceptions;

namespace DotCMISUnitTest
{
    [TestFixture]
    class SmokeTest : TestFramework
    {
        [Test]
        public void SmokeTestSession()
        {
            Assert.NotNull(Session);
            Assert.NotNull(Session.Binding);
            Assert.NotNull(Session.RepositoryInfo);
            Assert.NotNull(Session.RepositoryInfo.Id);
            Assert.NotNull(Session.RepositoryInfo.RootFolderId);
            Assert.NotNull(Session.DefaultContext);
            Assert.NotNull(Session.ObjectFactory);

            Assert.AreEqual("test", Session.CreateObjectId("test").Id);
        }

        [Test]
        public void SmokeTestTypes()
        {
            // getTypeDefinition
            IObjectType documentType = Session.GetTypeDefinition("cmis:document");
            Assert.NotNull(documentType);
            Assert.True(documentType is DocumentType);
            Assert.AreEqual("cmis:document", documentType.Id);
            Assert.AreEqual(BaseTypeId.CmisDocument, documentType.BaseTypeId);
            Assert.True(documentType.IsBaseType);
            Assert.IsNullOrEmpty(documentType.ParentTypeId);
            Assert.NotNull(documentType.PropertyDefintions);
            Assert.True(documentType.PropertyDefintions.Count >= 9);

            IObjectType folderType = Session.GetTypeDefinition("cmis:folder");
            Assert.NotNull(folderType);
            Assert.True(folderType is FolderType);
            Assert.AreEqual("cmis:folder", folderType.Id);
            Assert.AreEqual(BaseTypeId.CmisFolder, folderType.BaseTypeId);
            Assert.True(folderType.IsBaseType);
            Assert.IsNullOrEmpty(folderType.ParentTypeId);
            Assert.NotNull(folderType.PropertyDefintions);
            Assert.True(folderType.PropertyDefintions.Count >= 9);

            // getTypeChildren
            Session.Clear();

            IItemEnumerable<IObjectType> children = Session.GetTypeChildren(null, true);
            Assert.NotNull(children);

            int count;
            count = 0;
            foreach (IObjectType type in children)
            {
                Assert.NotNull(type);
                Assert.NotNull(type.Id);
                Assert.True(type.IsBaseType);
                Assert.IsNullOrEmpty(type.ParentTypeId);
                Assert.NotNull(type.PropertyDefintions);

                Session.Clear();
                IObjectType type2 = Session.GetTypeDefinition(type.Id);
                AssertAreEqual(type, type2);

                Session.GetTypeChildren(type.Id, true);

                count++;
            }

            Assert.True(count >= 2);
            Assert.True(count <= 4);

            // getTypeDescendants
            Session.Clear();

            IList<ITree<IObjectType>> descendants = Session.GetTypeDescendants(null, -1, true);

            count = 0;
            foreach (ITree<IObjectType> tree in descendants)
            {
                Assert.NotNull(tree);
                Assert.NotNull(tree.Item);

                IObjectType type = tree.Item;
                Assert.NotNull(type);
                Assert.NotNull(type.Id);
                Assert.True(type.IsBaseType);
                Assert.IsNullOrEmpty(type.ParentTypeId);
                Assert.NotNull(type.PropertyDefintions);

                Session.Clear();
                IObjectType type2 = Session.GetTypeDefinition(type.Id);
                AssertAreEqual(type, type2);

                Session.GetTypeDescendants(type.Id, 2, true);

                count++;
            }

            Assert.True(count >= 2);
            Assert.True(count <= 4);
        }

        [Test]
        public void SmokeTestRootFolder()
        {
            ICmisObject rootFolderObject = Session.GetRootFolder();

            Assert.NotNull(rootFolderObject);
            Assert.NotNull(rootFolderObject.Id);
            Assert.True(rootFolderObject is IFolder);

            IFolder rootFolder = (IFolder)rootFolderObject;

            Assert.AreEqual("/", rootFolder.Path);
            Assert.AreEqual(1, rootFolder.Paths.Count);

            Assert.NotNull(rootFolder.AllowableActions);
            Assert.True(rootFolder.AllowableActions.Actions.Contains(Actions.CanGetProperties));
            Assert.False(rootFolder.AllowableActions.Actions.Contains(Actions.CanGetFolderParent));

            IItemEnumerable<ICmisObject> children = rootFolder.GetChildren();
            Assert.NotNull(children);
            foreach (ICmisObject child in children)
            {
                Assert.NotNull(child);
                Assert.NotNull(child.Id);
                Assert.NotNull(child.Name);
                Console.WriteLine(child.Name + " (" + child.Id + ")");
            }
        }

        [Test]
        public void SmokeTestQuery()
        {
            IItemEnumerable<IQueryResult> qr = Session.Query("SELECT * FROM cmis:document", false);
            Assert.NotNull(qr);

            foreach (IQueryResult hit in qr)
            {
                Assert.NotNull(hit);
                Assert.NotNull(hit["cmis:objectId"]);
                Console.WriteLine(hit.GetPropertyValueById(PropertyIds.Name) + " (" + hit.GetPropertyValueById(PropertyIds.ObjectId) + ")");
            }
        }

        [Test]
        public void SmokeTestCreateDocument()
        {
            IDictionary<string, object> properties = new Dictionary<string, object>();
            properties[PropertyIds.Name] = "test-smoke.txt";
            properties[PropertyIds.ObjectTypeId] = DefaultDocumentType;

            byte[] content = UTF8Encoding.UTF8.GetBytes("Hello World!");

            ContentStream contentStream = new ContentStream();
            contentStream.FileName = properties[PropertyIds.Name] as string;
            contentStream.MimeType = "text/plain";
            contentStream.Length = content.Length;
            contentStream.Stream = new MemoryStream(content);

            IDocument doc = TestFolder.CreateDocument(properties, contentStream, null);

            // check doc
            Assert.NotNull(doc);
            Assert.NotNull(doc.Id);
            Assert.AreEqual(properties[PropertyIds.Name], doc.Name);
            Assert.AreEqual(BaseTypeId.CmisDocument, doc.BaseTypeId);
            Assert.True(doc.AllowableActions.Actions.Contains(Actions.CanGetProperties));
            Assert.False(doc.AllowableActions.Actions.Contains(Actions.CanGetChildren));

            // check versions
            IList<IDocument> versions = doc.GetAllVersions();
            Assert.NotNull(versions);
            Assert.AreEqual(1, versions.Count);
            //Assert.AreEqual(doc.Id, versions[0].Id);

            // check content
            IContentStream retrievedContentStream = doc.GetContentStream();
            Assert.NotNull(retrievedContentStream);
            Assert.NotNull(retrievedContentStream.Stream);

            MemoryStream byteStream = new MemoryStream();
            byte[] buffer = new byte[4096];
            int b = 1;
            while (b > 0)
            {
                b = retrievedContentStream.Stream.Read(buffer, 0, buffer.Length);
                byteStream.Write(buffer, 0, b);
            }

            byte[] retrievedContent = byteStream.ToArray();
            Assert.NotNull(retrievedContent);
            Assert.AreEqual(content.Length, retrievedContent.Length);
            for (int i = 0; i < content.Length; i++)
            {
                Assert.AreEqual(content[i], retrievedContent[i]);
            }

            // update name
            properties = new Dictionary<string, object>();
            properties[PropertyIds.Name] = "test2-smoke.txt";

            IObjectId newId = doc.UpdateProperties(properties);
            IDocument doc2 = Session.GetObject(newId) as IDocument;

            Assert.NotNull(doc2);

            doc2.Refresh();
            Assert.AreEqual(properties[PropertyIds.Name], doc2.Name);
            Assert.AreEqual(properties[PropertyIds.Name], doc2.GetPropertyValue(PropertyIds.Name));

            IProperty nameProperty = doc2[PropertyIds.Name];
            Assert.NotNull(nameProperty.PropertyType);
            Assert.AreEqual(properties[PropertyIds.Name], nameProperty.Value);
            Assert.AreEqual(properties[PropertyIds.Name], nameProperty.FirstValue);

            doc.Delete(true);

            try
            {
                doc.Refresh();
                Assert.Fail("Document shouldn't exist anymore!");
            }
            catch (CmisObjectNotFoundException) { }
        }

        [Test]
        public void SmokeTestVersioning()
        {
            IDictionary<string, object> properties = new Dictionary<string, object>();
            properties[PropertyIds.Name] = "test-version-smoke.txt";
            properties[PropertyIds.ObjectTypeId] = DefaultDocumentType;

            IDocument doc = TestFolder.CreateDocument(properties, null, null);
            Assert.NotNull(doc);
            Assert.NotNull(doc.Id);
            Assert.AreEqual(properties[PropertyIds.Name], doc.Name);

            IList<IDocument> versions = doc.GetAllVersions();
            Assert.NotNull(versions);
            Assert.AreEqual(1, versions.Count);

            IObjectId pwcId = doc.CheckOut();
            Assert.NotNull(pwcId);

            IDocument pwc = Session.GetObject(pwcId) as IDocument;

            // check PWC
            Assert.NotNull(pwc);
            Assert.NotNull(pwc.Id);
            Assert.AreEqual(BaseTypeId.CmisDocument, doc.BaseTypeId);

            IDictionary<string, object> newProperties = new Dictionary<string, object>();
            newProperties[PropertyIds.Name] = "test-version2-smoke.txt";

            IObjectId doc2Id = pwc.CheckIn(true, newProperties, null, "new DotCMIS version");
            Assert.NotNull(doc2Id);

            IDocument doc2 = Session.GetObject(doc2Id) as IDocument;
            doc2.Refresh();

            // check new version
            Assert.NotNull(doc2);
            Assert.NotNull(doc2.Id);
            Assert.AreEqual(newProperties[PropertyIds.Name], doc2.Name);
            Assert.AreEqual(BaseTypeId.CmisDocument, doc2.BaseTypeId);

            versions = doc2.GetAllVersions();
            Assert.NotNull(versions);
            Assert.AreEqual(2, versions.Count);

            doc2.DeleteAllVersions();

            try
            {
                doc2.Refresh();
                Assert.Fail("Document shouldn't exist anymore!");
            }
            catch (CmisObjectNotFoundException) { }
        }

        [Test]
        public void SmokeTestCreateFolder()
        {
            IDictionary<string, object> properties = new Dictionary<string, object>();
            properties[PropertyIds.Name] = "test-smoke";
            properties[PropertyIds.ObjectTypeId] = DefaultFolderType;

            IFolder folder = TestFolder.CreateFolder(properties);

            // check folder
            Assert.NotNull(folder);
            Assert.NotNull(folder.Id);
            Assert.AreEqual(properties[PropertyIds.Name], folder.Name);
            Assert.AreEqual(BaseTypeId.CmisFolder, folder.BaseTypeId);
            Assert.AreEqual(TestFolder.Id, folder.FolderParent.Id);
            Assert.False(folder.IsRootFolder);
            Assert.True(folder.Path.StartsWith("/"));
            Assert.True(folder.AllowableActions.Actions.Contains(Actions.CanGetProperties));
            Assert.True(folder.AllowableActions.Actions.Contains(Actions.CanGetChildren));
            Assert.False(folder.AllowableActions.Actions.Contains(Actions.CanGetContentStream));

            // check children
            foreach (ICmisObject cmisObject in folder.GetChildren())
            {
                Assert.Fail("Folder shouldn't have children!");
            }

            // check descendants
            bool? descSupport = Session.RepositoryInfo.Capabilities.IsGetDescendantsSupported;
            if (descSupport.HasValue && descSupport.Value)
            {
                IList<ITree<IFileableCmisObject>> list = folder.GetDescendants(-1);

                if (list != null)
                {
                    foreach (ITree<IFileableCmisObject> desc in list)
                    {
                        Assert.Fail("Folder shouldn't have children!");
                    }
                }
            }
            else
            {
                Console.WriteLine("GetDescendants not supported!");
            }

            // check folder tree
            bool? folderTreeSupport = Session.RepositoryInfo.Capabilities.IsGetFolderTreeSupported;
            if (folderTreeSupport.HasValue && folderTreeSupport.Value)
            {
                IList<ITree<IFileableCmisObject>> list = folder.GetFolderTree(-1);

                if (list != null)
                {
                    foreach (ITree<IFileableCmisObject> desc in list)
                    {
                        Assert.Fail("Folder shouldn't have children!");
                    }
                }
            }
            else
            {
                Console.WriteLine("GetFolderTree not supported!");
            }

            // check parents
            IFolder parent = folder.FolderParent;
            Assert.NotNull(parent);
            Assert.AreEqual(TestFolder.Id, parent.Id);

            IList<IFolder> parents = folder.Parents;
            Assert.NotNull(parents);
            Assert.True(parents.Count > 0);

            bool found = false;
            foreach (IFolder p in parents)
            {
                if (TestFolder.Id == p.Id)
                {
                    found = true;
                    break;
                }
            }
            Assert.True(found);

            folder.Delete(true);

            try
            {
                folder.Refresh();
                Assert.Fail("Folder shouldn't exist anymore!");
            }
            catch (CmisObjectNotFoundException) { }
        }

        [Test]
        public void SmokeTestContentChanges()
        {
            if (Session.RepositoryInfo.Capabilities.ChangesCapability != null)
            {
                if (Session.RepositoryInfo.Capabilities.ChangesCapability != CapabilityChanges.None)
                {
                    IChangeEvents changeEvents = Session.GetContentChanges(null, true, 1000);
                    Assert.NotNull(changeEvents);
                }
                else
                {
                    Console.WriteLine("Content changes not supported!");
                }
            }
            else
            {
                Console.WriteLine("ChangesCapability not set!");
            }
        }
    }
}
