﻿/*
 * 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.Enums;
using System.Collections;

namespace DotCMIS.Client.Impl
{
    /// <summary>
    /// Operation context implementation.
    /// </summary>
    public class OperationContext : IOperationContext
    {
        public const string PropertiesStar = "*";
        public const string RenditionNone = "cmis:none";

        private HashSet<string> filter;
        private bool includeAllowableActions;
        private bool includeAcls;
        private IncludeRelationshipsFlag? includeRelationships;
        private bool includePolicies;
        private HashSet<string> renditionFilter;
        private bool includePathSegments;
        private string orderBy;
        private bool cacheEnabled;
        private string cacheKey;
        private int maxItemsPerPage;

        public OperationContext()
        {
            filter = null;
            includeAcls = false;
            includeAllowableActions = true;
            includePolicies = false;
            includeRelationships = IncludeRelationshipsFlag.None;
            renditionFilter = null;
            includePathSegments = true;
            orderBy = null;
            cacheEnabled = false;
            maxItemsPerPage = 100;

            GenerateCacheKey();
        }

        public OperationContext(IOperationContext source)
        {
            filter = (source.Filter == null ? null : new HashSet<string>(source.Filter));
            includeAcls = source.IncludeAcls;
            includeAllowableActions = source.IncludeAllowableActions;
            includePolicies = source.IncludePolicies;
            includeRelationships = source.IncludeRelationships;
            renditionFilter = (source.RenditionFilter == null ? null : new HashSet<string>(source.RenditionFilter));
            includePathSegments = source.IncludePathSegments;
            orderBy = source.OrderBy;
            cacheEnabled = source.CacheEnabled;
            maxItemsPerPage = source.MaxItemsPerPage;

            GenerateCacheKey();
        }

        public OperationContext(HashSet<string> filter, bool includeAcls, bool includeAllowableActions,
            bool includePolicies, IncludeRelationshipsFlag includeRelationships, HashSet<string> renditionFilter,
            bool includePathSegments, String orderBy, bool cacheEnabled, int maxItemsPerPage)
        {
            this.filter = filter;
            this.includeAcls = includeAcls;
            this.includeAllowableActions = includeAllowableActions;
            this.includePolicies = includePolicies;
            this.includeRelationships = includeRelationships;
            this.renditionFilter = renditionFilter;
            this.includePathSegments = includePathSegments;
            this.orderBy = orderBy;
            this.cacheEnabled = cacheEnabled;
            this.maxItemsPerPage = maxItemsPerPage;

            GenerateCacheKey();
        }

        public HashSet<string> Filter
        {
            get { return filter == null ? null : new HashSet<string>(filter); }
            set
            {
                if (value != null)
                {
                    HashSet<string> tempSet = new HashSet<string>();
                    foreach (string oid in value)
                    {
                        if (oid == null) { continue; }

                        string toid = oid.Trim();
                        if (toid.Length == 0) { continue; }
                        if (toid == PropertiesStar)
                        {
                            tempSet = new HashSet<string>();
                            tempSet.Add(PropertiesStar);
                            break;
                        }
                        if (toid.IndexOf(',') > -1)
                        {
                            throw new ArgumentException("Query id must not contain a comma!");
                        }

                        tempSet.Add(toid);
                    }

                    if (tempSet.Count == 0) { filter = null; }
                    else { filter = tempSet; }
                }
                else
                {
                    filter = null;
                }

                GenerateCacheKey();
            }
        }

        public string FilterString
        {
            get
            {
                if (filter == null) { return null; }

                if (filter.Contains(PropertiesStar))
                {
                    return PropertiesStar;
                }

                this.filter.Add(PropertyIds.ObjectId);
                this.filter.Add(PropertyIds.BaseTypeId);
                this.filter.Add(PropertyIds.ObjectTypeId);

                StringBuilder sb = new StringBuilder();

                foreach (String oid in filter)
                {
                    if (sb.Length > 0) { sb.Append(','); }
                    sb.Append(oid);
                }

                return sb.ToString();
            }

            set
            {
                if (value == null || value.Trim().Length == 0)
                {
                    Filter = null;
                    return;
                }

                string[] ids = value.Split(',');
                HashSet<string> tempSet = new HashSet<string>();
                foreach (string qid in ids)
                {
                    tempSet.Add(qid);
                }

                Filter = tempSet;
            }
        }

        public bool IncludeAllowableActions
        {
            get { return includeAllowableActions; }
            set { includeAllowableActions = value; GenerateCacheKey(); }
        }

        public bool IncludeAcls
        {
            get { return includeAcls; }
            set { includeAcls = value; GenerateCacheKey(); }
        }

        public IncludeRelationshipsFlag? IncludeRelationships
        {
            get { return includeRelationships; }
            set { includeRelationships = value; GenerateCacheKey(); }
        }

        public bool IncludePolicies
        {
            get { return includePolicies; }
            set { includePolicies = value; GenerateCacheKey(); }
        }

        public HashSet<string> RenditionFilter
        {
            get { return renditionFilter == null ? null : new HashSet<string>(renditionFilter); }
            set
            {
                HashSet<string> tempSet = new HashSet<string>();
                if (value != null)
                {
                    foreach (String rf in value)
                    {
                        if (rf == null) { continue; }

                        String trf = rf.Trim();
                        if (trf.Length == 0) { continue; }
                        if (trf.IndexOf(',') > -1)
                        {
                            throw new ArgumentException("Rendition must not contain a comma!");
                        }

                        tempSet.Add(trf);
                    }

                    if (tempSet.Count == 0)
                    {
                        tempSet.Add(RenditionNone);
                    }
                }
                else
                {
                    tempSet.Add(RenditionNone);
                }

                renditionFilter = tempSet;

                GenerateCacheKey();
            }
        }

        public string RenditionFilterString
        {
            get
            {
                if (renditionFilter == null) { return null; }

                StringBuilder sb = new StringBuilder();
                foreach (string rf in renditionFilter)
                {
                    if (sb.Length > 0) { sb.Append(','); }
                    sb.Append(rf);
                }

                return sb.ToString();
            }

            set
            {
                if (value == null || value.Trim().Length == 0)
                {
                    RenditionFilter = null;
                    return;
                }

                string[] renditions = value.Split(',');
                HashSet<string> tempSet = new HashSet<string>();
                foreach (string rend in renditions)
                {
                    tempSet.Add(rend);
                }

                RenditionFilter = tempSet;
            }
        }

        public bool IncludePathSegments
        {
            get { return includePathSegments; }
            set { includePathSegments = value; GenerateCacheKey(); }
        }

        public string OrderBy
        {
            get { return orderBy; }
            set { orderBy = value; GenerateCacheKey(); }
        }

        public bool CacheEnabled
        {
            get { return cacheEnabled; }
            set { cacheEnabled = value; GenerateCacheKey(); }
        }

        public string CacheKey
        {
            get { return cacheKey; }
        }

        public int MaxItemsPerPage
        {
            get { return maxItemsPerPage; }
            set { maxItemsPerPage = value; }
        }

        protected void GenerateCacheKey()
        {
            if (!cacheEnabled)
            {
                cacheKey = null;
            }

            StringBuilder sb = new StringBuilder();

            sb.Append(includeAcls ? "1" : "0");
            sb.Append(includeAllowableActions ? "1" : "0");
            sb.Append(includePolicies ? "1" : "0");
            sb.Append("|");
            sb.Append(filter == null ? "" : FilterString);
            sb.Append("|");
            sb.Append(includeRelationships == null ? "" : includeRelationships.GetCmisValue());

            sb.Append("|");
            sb.Append(renditionFilter == null ? "" : RenditionFilterString);

            cacheKey = sb.ToString();
        }
    }

    /// <summary>
    /// Object id implementation.
    /// </summary>
    public class ObjectId : IObjectId
    {
        private string id;
        public string Id
        {
            get { return id; }
            set
            {
                if (value == null || value.Length == 0)
                {
                    throw new ArgumentException("Id must be set!");
                }

                id = value;
            }
        }

        public ObjectId(string id)
        {
            Id = id;
        }
    }

    /// <summary>
    /// Tree implementation.
    /// </summary>
    public class Tree<T> : ITree<T>
    {
        public T Item { get; set; }
        public IList<ITree<T>> Children { get; set; }
    }

    /// <summary>
    /// Base class for IItemEnumerable's.
    /// </summary>
    public abstract class AbstractEnumerable<T> : IItemEnumerable<T>
    {
        private AbstractEnumerator<T> enumerator;
        protected AbstractEnumerator<T> Enumerator
        {
            get
            {
                if (enumerator == null) { enumerator = CreateEnumerator(); }
                return enumerator;
            }
        }

        protected PageFetcher<T> PageFetcher { get; set; }
        protected long SkipCount { get; private set; }

        public AbstractEnumerable(PageFetcher<T> pageFetcher) :
            this(0, pageFetcher) { }

        protected AbstractEnumerable(long position, PageFetcher<T> pageFetcher)
        {
            this.PageFetcher = pageFetcher;
            this.SkipCount = position;
        }

        protected abstract AbstractEnumerator<T> CreateEnumerator();

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return Enumerator;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return Enumerator;
        }

        public IItemEnumerable<T> SkipTo(long position)
        {
            return new CollectionEnumerable<T>(position, PageFetcher);
        }

        public IItemEnumerable<T> GetPage()
        {
            return new CollectionPageEnumerable<T>(SkipCount, PageFetcher);
        }

        public IItemEnumerable<T> GetPage(int maxNumItems)
        {
            PageFetcher.MaxNumItems = maxNumItems;
            return new CollectionPageEnumerable<T>(SkipCount, PageFetcher);
        }

        public long PageNumItems { get { return Enumerator.PageNumItems; } }

        public bool HasMoreItems { get { return Enumerator.HasMoreItems; } }

        public long TotalNumItems { get { return Enumerator.TotalNumItems; } }
    }

    /// <summary>
    /// Abstract Enumerator implementation.
    /// </summary>
    public abstract class AbstractEnumerator<T> : IEnumerator<T>
    {
        private PageFetcher<T> pageFetcher;
        private PageFetcher<T>.Page<T> page = null;
        private long? totalNumItems = null;
        private bool? hasMoreItems = null;

        protected T current;

        public AbstractEnumerator(long skipCount, PageFetcher<T> pageFetcher)
        {
            this.SkipCount = skipCount;
            this.pageFetcher = pageFetcher;
        }

        T IEnumerator<T>.Current { get { return current; } }
        object IEnumerator.Current { get { return current; } }

        public void Reset()
        {
            throw new NotSupportedException();
        }

        public abstract bool MoveNext();

        public void Dispose() { }

        public long SkipCount { get; protected set; }

        public int SkipOffset { get; protected set; }

        public long Position { get { return SkipCount + SkipOffset; } }

        public long PageNumItems
        {
            get
            {
                PageFetcher<T>.Page<T> page = GetCurrentPage();
                if (page != null)
                {
                    IList<T> items = page.Items;
                    if (items != null)
                    {
                        return items.Count;
                    }
                }
                return 0;
            }
        }

        public long TotalNumItems
        {
            get
            {
                if (totalNumItems == null)
                {
                    totalNumItems = -1;
                    PageFetcher<T>.Page<T> page = GetCurrentPage();
                    if (page != null)
                    {
                        totalNumItems = page.TotalNumItems;
                    }
                }
                return (long)totalNumItems;
            }
        }

        public bool HasMoreItems
        {
            get
            {
                if (hasMoreItems == null)
                {
                    hasMoreItems = false;
                    PageFetcher<T>.Page<T> page = GetCurrentPage();
                    if (page != null)
                    {
                        if (page.HasMoreItems.HasValue)
                        {
                            hasMoreItems = page.HasMoreItems;
                        }
                    }
                }
                return (bool)hasMoreItems;
            }
        }

        protected int IncrementSkipOffset()
        {
            return SkipOffset++;
        }

        protected PageFetcher<T>.Page<T> GetCurrentPage()
        {
            if (page == null)
            {
                page = pageFetcher.FetchNextPage(SkipCount);
            }
            return page;
        }

        protected PageFetcher<T>.Page<T> IncrementPage()
        {
            SkipCount += SkipOffset;
            SkipOffset = 0;
            totalNumItems = null;
            hasMoreItems = null;
            page = pageFetcher.FetchNextPage(SkipCount);
            return page;
        }
    }

    /// <summary>
    /// Page fetcher.
    /// </summary>
    public class PageFetcher<T>
    {
        public delegate Page<T> FetchPage(long maxNumItems, long skipCount);

        private FetchPage fetchPageDelegate;

        public PageFetcher(long maxNumItems, FetchPage fetchPageDelegate)
        {
            MaxNumItems = maxNumItems;
            this.fetchPageDelegate = fetchPageDelegate;
        }

        public long MaxNumItems { get; set; }

        public Page<T> FetchNextPage(long skipCount)
        {
            return fetchPageDelegate(MaxNumItems, skipCount);
        }

        public class Page<P>
        {
            public Page(IList<P> items, long? totalNumItems, bool? hasMoreItems)
            {
                Items = items;
                TotalNumItems = totalNumItems;
                HasMoreItems = hasMoreItems;
            }

            public IList<P> Items { get; private set; }
            public long? TotalNumItems { get; private set; }
            public bool? HasMoreItems { get; private set; }
        }
    }

    /// <summary>
    /// CMIS Collection Enumerable.
    /// </summary>
    public class CollectionEnumerable<T> : AbstractEnumerable<T>
    {
        public CollectionEnumerable(PageFetcher<T> pageFetcher) :
            this(0, pageFetcher) { }

        public CollectionEnumerable(long position, PageFetcher<T> pageFetcher) :
            base(position, pageFetcher) { }

        protected override AbstractEnumerator<T> CreateEnumerator()
        {
            return new CollectionEnumerator<T>(SkipCount, PageFetcher);
        }
    }

    /// <summary>
    /// Enumerator for iterating over all items in a CMIS Collection.
    /// </summary>
    public class CollectionEnumerator<T> : AbstractEnumerator<T>
    {
        public CollectionEnumerator(long skipCount, PageFetcher<T> pageFetcher) :
            base(skipCount, pageFetcher) { }

        public override bool MoveNext()
        {
            PageFetcher<T>.Page<T> page = GetCurrentPage();
            if (page == null)
            {
                return false;
            }

            IList<T> items = page.Items;
            if (items == null || items.Count == 0)
            {
                return false;
            }

            if (SkipOffset == items.Count)
            {
                page = IncrementPage();
                items = page == null ? null : page.Items;
            }

            if (items == null || items.Count == 0 || SkipOffset == items.Count)
            {
                return false;
            }

            current = items[IncrementSkipOffset()];

            return true;
        }
    }

    /// <summary>
    /// Enumerable for a CMIS Collection Page.
    /// </summary>
    public class CollectionPageEnumerable<T> : AbstractEnumerable<T>
    {
        public CollectionPageEnumerable(PageFetcher<T> pageFetcher) :
            this(0, pageFetcher) { }

        public CollectionPageEnumerable(long position, PageFetcher<T> pageFetcher) :
            base(position, pageFetcher) { }

        protected override AbstractEnumerator<T> CreateEnumerator()
        {
            return new CollectionPageEnumerator<T>(SkipCount, PageFetcher);
        }
    }

    /// <summary>
    /// Enumerator for iterating over a page of items in a CMIS Collection.
    /// </summary>
    public class CollectionPageEnumerator<T> : AbstractEnumerator<T>
    {
        public CollectionPageEnumerator(long skipCount, PageFetcher<T> pageFetcher) :
            base(skipCount, pageFetcher) { }

        public override bool MoveNext()
        {
            PageFetcher<T>.Page<T> page = GetCurrentPage();
            if (page == null)
            {
                return false;
            }

            IList<T> items = page.Items;
            if (items == null || items.Count == 0 || SkipOffset == items.Count)
            {
                return false;
            }

            current = items[IncrementSkipOffset()];

            return true;
        }
    }
}
