﻿/*
 * 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 DotCMIS.Data;
using DotCMIS.Data.Impl;

namespace DotCMIS.Client.Impl
{
    /// <summary>
    /// Helper for all type implementations.
    /// </summary>
    internal class ObjectTypeHelper
    {
        private ISession session;
        private IObjectType objectType;
        private IObjectType baseType;
        private IObjectType parentType;

        public ObjectTypeHelper(ISession session, IObjectType objectType)
        {
            this.session = session;
            this.objectType = objectType;
        }

        public ISession Session { get { return session; } }

        public bool IsBaseType { get { return objectType.ParentTypeId == null || objectType.ParentTypeId.Length == 0; } }

        public IObjectType GetBaseType()
        {
            if (IsBaseType) { return null; }
            if (baseType != null) { return baseType; }

            baseType = session.GetTypeDefinition(objectType.BaseTypeId.GetCmisValue());

            return baseType;
        }

        public IObjectType GetParentType()
        {
            if (parentType != null) { return parentType; }
            if (objectType.ParentTypeId == null) { return null; }

            parentType = session.GetTypeDefinition(objectType.ParentTypeId);

            return parentType;
        }

        public IItemEnumerable<IObjectType> GetChildren()
        {
            return session.GetTypeChildren(objectType.Id, true);
        }

        public IList<ITree<IObjectType>> GetDescendants(int depth)
        {
            return session.GetTypeDescendants(objectType.Id, depth, true);
        }
    }

    /// <summary>
    /// Document type implementation.
    /// </summary>
    public class DocumentType : DocumentTypeDefinition, IDocumentType
    {
        private ObjectTypeHelper helper;

        public DocumentType(ISession session, IDocumentTypeDefinition typeDefinition)
        {
            Initialize(typeDefinition);
            ContentStreamAllowed = typeDefinition.ContentStreamAllowed;
            IsVersionable = typeDefinition.IsVersionable;
            helper = new ObjectTypeHelper(session, this);
        }

        public IObjectType GetBaseType() { return helper.GetBaseType(); }

        public IItemEnumerable<IObjectType> GetChildren() { return helper.GetChildren(); }

        public IList<ITree<IObjectType>> GetDescendants(int depth) { return helper.GetDescendants(depth); }

        public IObjectType GetParentType() { return helper.GetParentType(); }

        public bool IsBaseType { get { return helper.IsBaseType; } }
    }

    /// <summary>
    /// Folder type implementation.
    /// </summary>
    public class FolderType : FolderTypeDefinition, IFolderType
    {
        private ObjectTypeHelper helper;

        public FolderType(ISession session, IFolderTypeDefinition typeDefinition)
        {
            Initialize(typeDefinition);
            helper = new ObjectTypeHelper(session, this);
        }

        public IObjectType GetBaseType() { return helper.GetBaseType(); }

        public IItemEnumerable<IObjectType> GetChildren() { return helper.GetChildren(); }

        public IList<ITree<IObjectType>> GetDescendants(int depth) { return helper.GetDescendants(depth); }

        public IObjectType GetParentType() { return helper.GetParentType(); }

        public bool IsBaseType { get { return helper.IsBaseType; } }
    }

    /// <summary>
    /// Relationship type implementation.
    /// </summary>
    public class RelationshipType : RelationshipTypeDefinition, IRelationshipType
    {
        private ObjectTypeHelper helper;
        private IList<IObjectType> allowedSourceTypes;
        private IList<IObjectType> allowedTargetTypes;

        public RelationshipType(ISession session, IRelationshipTypeDefinition typeDefinition)
        {
            Initialize(typeDefinition);
            helper = new ObjectTypeHelper(session, this);
        }

        public IObjectType GetBaseType() { return helper.GetBaseType(); }

        public IItemEnumerable<IObjectType> GetChildren() { return helper.GetChildren(); }

        public IList<ITree<IObjectType>> GetDescendants(int depth) { return helper.GetDescendants(depth); }

        public IObjectType GetParentType() { return helper.GetParentType(); }

        public bool IsBaseType { get { return helper.IsBaseType; } }

        public IList<IObjectType> GetAllowedSourceTypes
        {
            get
            {
                if (allowedSourceTypes == null)
                {
                    IList<string> ids = AllowedSourceTypeIds;
                    IList<IObjectType> types = new List<IObjectType>(ids == null ? 0 : ids.Count);
                    if (ids != null)
                    {
                        foreach (String id in ids)
                        {
                            types.Add(helper.Session.GetTypeDefinition(id));
                        }
                    }
                    allowedSourceTypes = types;
                }
                return allowedSourceTypes;
            }
        }

        public IList<IObjectType> GetAllowedTargetTypes
        {
            get
            {
                if (allowedTargetTypes == null)
                {
                    IList<string> ids = AllowedTargetTypeIds;
                    IList<IObjectType> types = new List<IObjectType>(ids == null ? 0 : ids.Count);
                    if (ids != null)
                    {
                        foreach (String id in ids)
                        {
                            types.Add(helper.Session.GetTypeDefinition(id));
                        }
                    }
                    allowedTargetTypes = types;
                }
                return allowedTargetTypes;
            }
        }
    }

    /// <summary>
    /// Policy type implementation.
    /// </summary>
    public class PolicyType : PolicyTypeDefinition, IPolicyType
    {
        private ObjectTypeHelper helper;

        public PolicyType(ISession session, IPolicyTypeDefinition typeDefinition)
        {
            Initialize(typeDefinition);
            helper = new ObjectTypeHelper(session, this);
        }

        public IObjectType GetBaseType() { return helper.GetBaseType(); }

        public IItemEnumerable<IObjectType> GetChildren() { return helper.GetChildren(); }

        public IList<ITree<IObjectType>> GetDescendants(int depth) { return helper.GetDescendants(depth); }

        public IObjectType GetParentType() { return helper.GetParentType(); }

        public bool IsBaseType { get { return helper.IsBaseType; } }
    }
}
