﻿/*
 * 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.Binding;
using DotCMIS.Binding.Services;
using System.Threading;
using DotCMIS.Exceptions;
using DotCMIS.Data;
using DotCMIS.Data.Extensions;

namespace DotCMIS.Binding.Impl
{
    /// <summary>
    /// Binding layer implementation.
    /// </summary>
    internal class CmisBinding : ICmisBinding
    {
        private BindingSession session;
        private BindingsObjectFactory objectFactory;
        private BindingRepositoryService repositoryServiceWrapper;

        public CmisBinding(IDictionary<string, string> sessionParameters)
        {
            if (sessionParameters == null)
            {
                throw new ArgumentNullException("sessionParameters");
            }

            if (!sessionParameters.ContainsKey(SessionParameter.BindingSpiClass))
            {
                throw new ArgumentException("Session parameters do not contain a SPI class name!");
            }

            // initialize session
            session = new BindingSession();
            foreach (string key in sessionParameters.Keys)
            {
                session.PutValue(key, sessionParameters[key]);
            }

            // set up object factory
            objectFactory = new BindingsObjectFactory();

            // set up authentication provider
            string authenticationProviderClass;
            if (sessionParameters.TryGetValue(SessionParameter.AuthenticationProviderClass, out authenticationProviderClass))
            {
                try
                {
                    Type authProvType = Type.GetType(authenticationProviderClass);
                    AbstractAuthenticationProvider authenticationProvider = (AbstractAuthenticationProvider)Activator.CreateInstance(authProvType);
                    authenticationProvider.Session = session;
                    session.PutValue(BindingSession.AuthenticationProvider, authenticationProvider);
                }
                catch (Exception e)
                {
                    throw new CmisRuntimeException("Could not load authentictaion provider: " + e.Message, e);
                }
            }

            // initialize the SPI
            GetSpi();

            // set up caches
            ClearAllCaches();

            // set up repository service
            repositoryServiceWrapper = new BindingRepositoryService(session);
        }

        public IRepositoryService GetRepositoryService()
        {
            CheckSession();
            return repositoryServiceWrapper;
        }

        public INavigationService GetNavigationService()
        {
            CheckSession();
            ICmisSpi spi = GetSpi();
            return spi.GetNavigationService();
        }

        public IObjectService GetObjectService()
        {
            CheckSession();
            ICmisSpi spi = GetSpi();
            return spi.GetObjectService();
        }

        public IVersioningService GetVersioningService()
        {
            CheckSession();
            ICmisSpi spi = GetSpi();
            return spi.GetVersioningService();
        }

        public IRelationshipService GetRelationshipService()
        {
            CheckSession();
            ICmisSpi spi = GetSpi();
            return spi.GetRelationshipService();
        }

        public IDiscoveryService GetDiscoveryService()
        {
            CheckSession();
            ICmisSpi spi = GetSpi();
            return spi.GetDiscoveryService();
        }

        public IMultiFilingService GetMultiFilingService()
        {
            CheckSession();
            ICmisSpi spi = GetSpi();
            return spi.GetMultiFilingService();
        }

        public IAclService GetAclService()
        {
            CheckSession();
            ICmisSpi spi = GetSpi();
            return spi.GetAclService();
        }

        public IPolicyService GetPolicyService()
        {
            CheckSession();
            ICmisSpi spi = GetSpi();
            return spi.GetPolicyService();
        }

        public IBindingsObjectFactory GetObjectFactory()
        {
            return objectFactory;
        }

        public void ClearAllCaches()
        {
            CheckSession();

            session.Lock();
            try
            {
                session.PutValue(BindingSession.RepositoryInfoCache, new RepositoryInfoCache(session));
                session.PutValue(BindingSession.TypeDefinitionCache, new TypeDefinitionCache(session));

                ICmisSpi spi = GetSpi();
                spi.ClearAllCaches();
            }
            finally
            {
                session.Unlock();
            }
        }

        public void ClearRepositoryCache(string repositoryId)
        {
            CheckSession();

            if (repositoryId == null)
            {
                return;
            }

            session.Lock();
            try
            {
                RepositoryInfoCache repInfoCache = session.GetRepositoryInfoCache();
                repInfoCache.Remove(repositoryId);

                TypeDefinitionCache typeDefCache = session.GetTypeDefinitionCache();
                typeDefCache.Remove(repositoryId);

                ICmisSpi spi = GetSpi();
                spi.ClearRepositoryCache(repositoryId);
            }
            finally
            {
                session.Unlock();
            }
        }

        public void Close()
        {
            CheckSession();

            session.Lock();
            try
            {
                GetSpi().Close();
            }
            finally
            {
                session.Unlock();
                session = null;
            }
        }

        private void CheckSession()
        {
            if (session == null)
            {
                throw new ApplicationException("Already closed.");
            }
        }

        private ICmisSpi GetSpi()
        {
            return session.GetSpi();
        }
    }

    /// <summary>
    /// Session object implementation of the binding layer.
    /// </summary>
    internal class BindingSession : IBindingSession
    {
        public const string RepositoryInfoCache = "org.apache.chemistry.dotcmis.bindings.repositoryInfoCache";
        public const string TypeDefinitionCache = "org.apache.chemistry.dotcmis.bindings.typeDefintionCache";
        public const string AuthenticationProvider = "org.apache.chemistry.dotcmis.bindings.authenticationProvider";
        public const string SpiObject = "org.apache.chemistry.dotcmis.bindings.spi.object";

        private Dictionary<string, object> data;
        private object sessionLock = new object();

        public BindingSession()
        {
            data = new Dictionary<string, object>();
        }

        public object GetValue(string key)
        {
            return GetValue(key, null);
        }

        public object GetValue(string key, object defValue)
        {
            object result = null;

            Lock();
            try
            {
                if (data.TryGetValue(key, out result))
                {
                    return result;
                }
                else
                {
                    return defValue;
                }
            }
            finally
            {
                Unlock();
            }
        }

        public int GetValue(string key, int defValue)
        {
            object value = GetValue(key);

            try
            {
                if (value is string)
                {
                    return Int32.Parse((string)value);
                }
                else if (value is int)
                {
                    return (int)value;
                }
            }
            catch (Exception)
            {
            }

            return defValue;
        }

        public void PutValue(string key, object value)
        {
            Lock();
            try
            {
                data[key] = value;
            }
            finally
            {
                Unlock();
            }
        }

        public void RemoveValue(string key)
        {
            Lock();
            try
            {
                data.Remove(key);
            }
            finally
            {
                Unlock();
            }
        }

        public ICmisSpi GetSpi()
        {
            Lock();
            try
            {
                ICmisSpi spi = GetValue(SpiObject) as ICmisSpi;
                if (spi != null)
                {
                    return spi;
                }


                // ok, we have to create it...
                try
                {
                    object spiObject;
                    if (data.TryGetValue(SessionParameter.BindingSpiClass, out spiObject))
                    {
                        string spiClassName = spiObject as string;
                        if (spiClassName != null)
                        {
                            Type spiClass = Type.GetType(spiClassName);
                            spi = (ICmisSpi)Activator.CreateInstance(spiClass);
                            spi.initialize(this);
                        }
                        else
                        {
                            throw new CmisRuntimeException("SPI class is not set!");
                        }
                    }
                    else
                    {
                        throw new CmisRuntimeException("SPI class is not set!");
                    }
                }
                catch (CmisBaseException ce)
                {
                    throw ce;
                }
                catch (Exception e)
                {
                    throw new CmisRuntimeException("SPI cannot be initialized: " + e.Message, e);
                }

                // we have a SPI object -> put it into the session
                data[SpiObject] = spi;

                return spi;
            }
            finally
            {
                Unlock();
            }
        }

        public RepositoryInfoCache GetRepositoryInfoCache()
        {
            return GetValue(RepositoryInfoCache) as RepositoryInfoCache;
        }

        public TypeDefinitionCache GetTypeDefinitionCache()
        {
            return GetValue(TypeDefinitionCache) as TypeDefinitionCache;
        }

        public AbstractAuthenticationProvider GetAuthenticationProvider()
        {
            return GetValue(AuthenticationProvider) as AbstractAuthenticationProvider;
        }

        public void Lock()
        {
            Monitor.Enter(sessionLock);
        }

        public void Unlock()
        {
            Monitor.Exit(sessionLock);
        }

        public override string ToString()
        {
            return data.ToString();
        }
    }

    /// <summary>
    /// Repository service proxy that caches repository infos and type defintions.
    /// </summary>
    internal class BindingRepositoryService : IRepositoryService
    {
        private BindingSession session;

        public BindingRepositoryService(BindingSession session)
        {
            this.session = session;
        }

        public IList<IRepositoryInfo> GetRepositoryInfos(IExtensionsData extension)
        {
            IList<IRepositoryInfo> result = null;
            bool hasExtension = (extension != null) && (extension.Extensions != null) && (extension.Extensions.Count > 0);

            // get the SPI and fetch the repository infos
            ICmisSpi spi = session.GetSpi();
            result = spi.GetRepositoryService().GetRepositoryInfos(extension);

            // put it into the cache
            if (!hasExtension && (result != null))
            {
                RepositoryInfoCache cache = session.GetRepositoryInfoCache();
                foreach (RepositoryInfo rid in result)
                {
                    cache.Put(rid);
                }
            }

            return result;
        }

        public IRepositoryInfo GetRepositoryInfo(string repositoryId, IExtensionsData extension)
        {
            IRepositoryInfo result = null;
            bool hasExtension = (extension != null) && (extension.Extensions != null) && (extension.Extensions.Count > 0);

            RepositoryInfoCache cache = session.GetRepositoryInfoCache();

            // if extension is not set, check the cache first
            if (!hasExtension)
            {
                result = cache.Get(repositoryId);
                if (result != null)
                {
                    return result;
                }
            }

            // it was not in the cache -> get the SPI and fetch the repository info
            ICmisSpi spi = session.GetSpi();
            result = spi.GetRepositoryService().GetRepositoryInfo(repositoryId, extension);

            // put it into the cache
            if (!hasExtension)
            {
                cache.Put(result);
            }

            return result;
        }

        public ITypeDefinitionList GetTypeChildren(string repositoryId, string typeId, bool? includePropertyDefinitions,
                long? maxItems, long? skipCount, IExtensionsData extension)
        {
            ITypeDefinitionList result = null;
            bool hasExtension = (extension != null) && (extension.Extensions != null) && (extension.Extensions.Count > 0);

            // get the SPI and fetch the type definitions
            ICmisSpi spi = session.GetSpi();
            result = spi.GetRepositoryService().GetTypeChildren(repositoryId, typeId, includePropertyDefinitions, maxItems,
                    skipCount, extension);

            // put it into the cache
            if (!hasExtension && (includePropertyDefinitions ?? false) && (result != null))
            {
                TypeDefinitionCache cache = session.GetTypeDefinitionCache();
                foreach (ITypeDefinition tdd in result.List)
                {
                    cache.Put(repositoryId, tdd);
                }
            }

            return result;
        }

        public IList<ITypeDefinitionContainer> GetTypeDescendants(string repositoryId, string typeId, long? depth,
                bool? includePropertyDefinitions, IExtensionsData extension)
        {
            IList<ITypeDefinitionContainer> result = null;
            bool hasExtension = (extension != null) && (extension.Extensions != null) && (extension.Extensions.Count > 0);

            // get the SPI and fetch the type definitions
            ICmisSpi spi = session.GetSpi();
            result = spi.GetRepositoryService().GetTypeDescendants(repositoryId, typeId, depth, includePropertyDefinitions,
                    extension);

            // put it into the cache
            if (!hasExtension && (includePropertyDefinitions ?? false) && (result != null))
            {
                TypeDefinitionCache cache = session.GetTypeDefinitionCache();
                AddToTypeCache(cache, repositoryId, result);
            }

            return result;
        }

        private void AddToTypeCache(TypeDefinitionCache cache, string repositoryId, IList<ITypeDefinitionContainer> containers)
        {
            if (containers == null)
            {
                return;
            }

            foreach (ITypeDefinitionContainer container in containers)
            {
                cache.Put(repositoryId, container.TypeDefinition);
                AddToTypeCache(cache, repositoryId, container.Children);
            }
        }

        public ITypeDefinition GetTypeDefinition(string repositoryId, string typeId, IExtensionsData extension)
        {
            ITypeDefinition result = null;
            bool hasExtension = (extension != null) && (extension.Extensions != null) && (extension.Extensions.Count > 0);

            TypeDefinitionCache cache = session.GetTypeDefinitionCache();

            // if extension is not set, check the cache first
            if (!hasExtension)
            {
                result = cache.Get(repositoryId, typeId);
                if (result != null)
                {
                    return result;
                }
            }

            // it was not in the cache -> get the SPI and fetch the type definition
            ICmisSpi spi = session.GetSpi();
            result = spi.GetRepositoryService().GetTypeDefinition(repositoryId, typeId, extension);

            // put it into the cache
            if (!hasExtension && (result != null))
            {
                cache.Put(repositoryId, result);
            }

            return result;
        }
    }

    /// <summary>
    /// Object factory implementation.
    /// </summary>
    internal class BindingsObjectFactory : IBindingsObjectFactory
    {
    }

    /// <summary>
    /// SPI interface.
    /// </summary>
    internal interface ICmisSpi
    {
        void initialize(BindingSession session);

        IRepositoryService GetRepositoryService();

        INavigationService GetNavigationService();

        IObjectService GetObjectService();

        IVersioningService GetVersioningService();

        IRelationshipService GetRelationshipService();

        IDiscoveryService GetDiscoveryService();

        IMultiFilingService GetMultiFilingService();

        IAclService GetAclService();

        IPolicyService GetPolicyService();

        void ClearAllCaches();

        void ClearRepositoryCache(string repositoryId);

        void Close();
    }
}
