﻿/*
 * 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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotCMIS.Data;
using DotCMIS.Enums;
using DotCMIS.Data.Extensions;
using DotCMIS.Binding;

namespace DotCMIS.Client
{
    public interface ISessionFactory
    {
        ISession CreateSession(IDictionary<string, string> parameters);
        IList<IRepository> GetRepositories(IDictionary<string, string> parameters);
    }

    public interface IRepository : IRepositoryInfo
    {
        ISession CreateSession();
    }

    public interface ISession
    {
        void Clear();

        // session context

        ICmisBinding Binding { get; }

        IOperationContext DefaultContext { get; set; }
        IOperationContext CreateOperationContext();
        IOperationContext CreateOperationContext(HashSet<string> filter, bool includeAcls, bool includeAllowableActions, bool includePolicies,
            IncludeRelationshipsFlag includeRelationships, HashSet<string> renditionFilter, bool includePathSegments, string orderBy, 
            bool cacheEnabled, int maxItemsPerPage);
        IObjectId CreateObjectId(string id);

        // services

        IRepositoryInfo RepositoryInfo { get; }
        IObjectFactory ObjectFactory { get; }

        // types

        IObjectType GetTypeDefinition(string typeId);
        IItemIterable<IObjectType> GetTypeChildren(string typeId, bool includePropertyDefinitions);
        IList<ITree<IObjectType>> GetTypeDescendants(string typeId, int depth, bool includePropertyDefinitions);

        // navigation

        IFolder GetRootFolder();
        IFolder GetRootFolder(IOperationContext context);
        IItemIterable<IDocument> GetCheckedOutDocs();
        IItemIterable<IDocument> GetCheckedOutDocs(IOperationContext context);
        ICmisObject GetObject(IObjectId objectId);
        ICmisObject GetObject(IObjectId objectId, IOperationContext context);
        ICmisObject GetObjectByPath(string path);
        ICmisObject GetObjectByPath(string path, IOperationContext context);

        // discovery

        IItemIterable<IQueryResult> Query(string statement, bool searchAllVersions);
        IItemIterable<IQueryResult> query(string statement, bool searchAllVersions, IOperationContext context);
        IChangeEvents getContentChanges(string changeLogToken, bool includeProperties, long maxNumItems);
        IChangeEvents getContentChanges(string changeLogToken, bool includeProperties, long maxNumItems,
                IOperationContext context);

        // create

        IObjectId CreateDocument(IDictionary<string, string> properties, IObjectId folderId, IContentStream contentStream,
                VersioningState? versioningState, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces);
        IObjectId CreateDocument(IDictionary<string, string> properties, IObjectId folderId, IContentStream contentStream,
                VersioningState? versioningState);
        IObjectId CreateDocumentFromSource(IObjectId source, IDictionary<string, string> properties, IObjectId folderId,
                VersioningState? versioningState, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces);
        IObjectId CreateDocumentFromSource(IObjectId source, IDictionary<string, string> properties, IObjectId folderId,
                VersioningState? versioningState);
        IObjectId CreateFolder(IDictionary<string, string> properties, IObjectId folderId, IList<IPolicy> policies, IList<IAce> addAces,
                IList<IAce> removeAces);
        IObjectId CreateFolder(IDictionary<string, string> properties, IObjectId folderId);
        IObjectId CreatePolicy(IDictionary<string, string> properties, IObjectId folderId, IList<IPolicy> policies, IList<IAce> addAces,
                IList<IAce> removeAces);
        IObjectId CreatePolicy(IDictionary<string, string> properties, IObjectId folderId);
        IObjectId CreateRelationship(IDictionary<string, string> properties, IList<IPolicy> policies, IList<IAce> addAces,
                IList<IAce> removeAces);
        IObjectId CreateRelationship(IDictionary<string, string> properties);

        IItemIterable<IRelationship> GetRelationships(IObjectId objectId, bool includeSubRelationshipTypes,
                RelationshipDirection? relationshipDirection, IObjectType type, IOperationContext context);

        // permissions

        IAcl GetAcl(IObjectId objectId, bool onlyBasicPermissions);
        IAcl ApplyAcl(IObjectId objectId, IList<IAce> addAces, IList<IAce> removeAces, AclPropagation? aclPropagation);
        void ApplyPolicy(IObjectId objectId, IObjectId policyIds);
        void RemovePolicy(IObjectId objectId, IObjectId policyIds);
    }

    public interface IObjectFactory { }

    public interface IOperationContext
    {
        HashSet<string> Filter { get; set; }
        string FilterString { get; set; }
        bool IncludeAllowableActions { get; set; }
        bool IncludeAcls { get; set; }
        IncludeRelationshipsFlag? IncludeRelationships { get; set; }
        bool IncludePolicies { get; set; }
        HashSet<string> RenditionFilter { get; set; }
        string RenditionFilterString { get; set; }
        bool IncludePathSegments { get; set; }
        string OrderBy { get; set; }
        bool CacheEnabled { get; set; }
        string CacheKey { get; }
        int MaxItemsPerPage { get; set; }
    }

    public interface ITree<T>
    {
        T Item { get; }
        IList<ITree<T>> GetChildren();
    }

    public interface IObjectType : ITypeDefinition
    {
        bool IsBaseType { get; }
        IObjectType BaseType { get; }
        IObjectType ParentType { get; }
        IItemIterable<IObjectType> GetChildren();
        IList<ITree<IObjectType>> GetDescendants(int depth);
    }

    public interface IItemIterable<T>
    {
        IItemIterable<T> SkipTo(long position);
        IItemIterable<T> GetPage();
        IItemIterable<T> GetPage(int maxNumItems);
        long PageNumItems { get; }
        bool HasMoreItems { get; }
        long TotalNumItems { get; }
    }

    public interface IObjectId
    {
        string Id { get; }
    }

    public interface IRendition : IRenditionData
    {
        IDocument GetRenditionDocument();
        IDocument GetRenditionDocument(IOperationContext context);
        IContentStream GetContentStream();
    }

    public interface IProperty : IPropertyData
    {
        bool IsMultiValued { get; }
        PropertyType PropertyType { get; }
        PropertyDefinition PropertyDefinition { get; }
        V GetValue<V>();
        string GetValueAsString();
        string GetValuesAsString();
    }

    public interface ICmisObjectProperties
    {
        IList<IProperty> Properties { get; }
        IProperty GetProperty(string id);
        T GetPropertyValue<T>(string id);

        // convenience accessors
        string Name { get; }
        string CreatedBy { get; }
        DateTime CreationDate { get; }
        string LastModifiedBy { get; }
        DateTime LastModificationDate { get; }
        BaseTypeId BaseTypeId { get; }
        IObjectType BaseType { get; }
        IObjectType Type { get; }
        string ChangeToken { get; }
    }

    public enum ExtensionLevel
    {

        Object, Properties, AllowableActions, Acl, Policies, ChangeEvent
    }

    public interface ICmisObject : IObjectId, ICmisObjectProperties
    {
        // object
        IAllowableActions GetAllowableActions();
        IList<IRelationship> GetRelationships();
        IAcl GetAcl();

        // object service
        void Delete(bool allVersions);
        ICmisObject UpdateProperties(IDictionary<string, object> properties);
        IObjectId UpdateProperties(IDictionary<string, object> properties, bool refresh);

        // renditions
        IList<IRendition> GetRenditions();

        // policy service
        void ApplyPolicy(IObjectId policyId);
        void RemovePolicy(IObjectId policyIds);
        IList<IPolicy> GetPolicies();

        // ACL service
        IAcl applyAcl(IList<IAce> AddAces, IList<IAce> removeAces, AclPropagation? aclPropagation);
        IAcl addAcl(IList<IAce> AddAces, AclPropagation? aclPropagation);
        IAcl removeAcl(IList<IAce> RemoveAces, AclPropagation? aclPropagation);

        // extensions
        IList<ICmisExtensionElement> GetExtensions(ExtensionLevel level);

        long GetRefreshTimestamp();
        void Refresh();
        void RefreshIfOld(long durationInMillis);
    }

    public interface IFileableCmisObject : ICmisObject
    {
        // object service
        IFileableCmisObject Move(IObjectId sourceFolderId, IObjectId targetFolderId);

        // navigation service
        IList<IFolder> GetParents();
        IList<string> GetPaths();

        // multifiling service
        void AddToFolder(IObjectId folderId, bool allVersions);
        void RemoveFromFolder(IObjectId folderId);
    }

    public interface IDocumentProperties
    {
        bool? IsImmutable { get; }
        bool? IsLatestVersion { get; }
        bool? IsMajorVersion { get; }
        bool? IsLatestMajorVersion { get; }
        string VersionLabel { get; }
        string VersionSeriesId { get; }
        bool? VersionSeriesCheckedOut { get; }
        string VersionSeriesCheckedOutBy { get; }
        string VersionSeriesCheckedOutId { get; }
        string CheckinComment { get; }
        long ContentStreamLength { get; }
        string ContentStreamMimeType { get; }
        string ContentStreamFileName { get; }
        string ContentStreamId { get; }
    }

    public interface IDocument : IFileableCmisObject, IDocumentProperties
    {
        void DeleteAllVersions();
        IContentStream GetContentStream();
        IContentStream GetContentStream(string streamId);
        IDocument SetContentStream(IContentStream contentStream, bool overwrite);
        IObjectId SetContentStream(IContentStream contentStream, bool overwrite, bool refresh);
        IDocument DeleteContentStream();
        IObjectId DeleteContentStream(bool refresh);
        IObjectId CheckOut();
        void CancelCheckOut();
        IObjectId CheckIn(bool major, IDictionary<string, object> properties, IContentStream contentStream, string checkinComment,
                IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces);
        IObjectId checkIn(bool major, IDictionary<string, object> properties, IContentStream contentStream, string checkinComment);
        IDocument GetObjectOfLatestVersion(bool major);
        IDocument GetObjectOfLatestVersion(bool major, IOperationContext context);
        IList<IDocument> GetAllVersions();
        IList<IDocument> GetAllVersions(IOperationContext context);
        IDocument Copy(IObjectId targetFolderId);
        IDocument Copy(IObjectId targetFolderId, IDictionary<string, object> properties, VersioningState? versioningState,
                IList<IPolicy> policies, IList<IAce> addACEs, IList<IAce> removeACEs, IOperationContext context);
    }

    public interface IFolderProperties
    {
        IList<IObjectType> AllowedChildObjectTypes { get; }
    }

    public interface IFolder : IFileableCmisObject, IFolderProperties
    {
        IDocument CreateDocument(IDictionary<string, object> properties, IContentStream contentStream, VersioningState? versioningState,
                IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context);
        IDocument CreateDocument(IDictionary<string, object> properties, IContentStream contentStream, VersioningState? versioningState);
        IDocument CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, VersioningState? versioningState,
                IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context);
        IDocument CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, VersioningState? versioningState);
        IFolder CreateFolder(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces,
                IOperationContext context);
        IFolder CreateFolder(IDictionary<string, object> properties);
        IPolicy CreatePolicy(IDictionary<string, object> properties, List<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces,
                IOperationContext context);
        IPolicy CreatePolicy(IDictionary<string, object> properties);
        IList<string> DeleteTree(bool allversions, UnfileObject? unfile, bool continueOnFailure);
        IList<ITree<IFileableCmisObject>> GetFolderTree(int depth);
        IList<ITree<IFileableCmisObject>> GetFolderTree(int depth, IOperationContext context);
        IList<ITree<IFileableCmisObject>> GetDescendants(int depth);
        IList<ITree<IFileableCmisObject>> GetDescendants(int depth, IOperationContext context);
        IItemIterable<ICmisObject> GetChildren();
        IItemIterable<ICmisObject> GetChildren(IOperationContext context);
        bool IsRootFolder { get; }
        IFolder FolderParent { get; }
        string Path { get; }
        IItemIterable<IDocument> GetCheckedOutDocs();
        IItemIterable<IDocument> GetCheckedOutDocs(IOperationContext context);
    }

    public interface IPolicyProperties
    {
        string PolicyText { get; }
    }

    public interface IPolicy : IFileableCmisObject, IPolicyProperties
    {
    }

    public interface IRelationshipProperties
    {
        IObjectId SourceId { get; }
        IObjectId TargetId { get; }
    }

    public interface IRelationship : ICmisObject, IRelationshipProperties
    {
        ICmisObject GetSource();
        ICmisObject GetSource(IOperationContext context);
        ICmisObject GetTarget();
        ICmisObject GetTarget(IOperationContext context);
    }

    public interface IQueryResult
    {
    }

    public interface IChangeEvents
    {
    }
}
