﻿/*
 * 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.Threading;
using DotCMIS.Binding.Services;
using DotCMIS.Data;
using DotCMIS.Data.Extensions;
using DotCMIS.Exceptions;

namespace DotCMIS.Binding.Impl
{
    /// <summary>
    /// Binding layer implementation.
    /// </summary>
    internal class CmisBinding : ICmisBinding
    {
        private BindingSession session;
        private BindingRepositoryService repositoryServiceWrapper;

        public CmisBinding(IDictionary<string, string> sessionParameters)
            : this(sessionParameters, null)
        {
        }

        public CmisBinding(IDictionary<string, string> sessionParameters, AbstractAuthenticationProvider authenticationProvider)
        {
            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 authentication provider
            if (authenticationProvider == null)
            {
                string authenticationProviderClass;
                if (sessionParameters.TryGetValue(SessionParameter.AuthenticationProviderClass, out authenticationProviderClass))
                {
                    try
                    {
                        Type authProvType = Type.GetType(authenticationProviderClass);
                        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);
                    }
                }
            }
            else
            {
                authenticationProvider.Session = session;
                session.PutValue(BindingSession.AuthenticationProvider, authenticationProvider);
            }

            // initialize the SPI
            GetSpi();

            // set up caches
            ClearAllCaches();

            // set up repository service
            repositoryServiceWrapper = new BindingRepositoryService(session);
        }

        public string BindingType
        {
            get
            {
                CheckSession();

                string bindingType = session.GetValue(SessionParameter.BindingType) as string;

                if (bindingType == null)
                {
                    bindingType = DotCMIS.BindingType.Custom;
                }

                return bindingType;
            }
        }
        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 IAuthenticationProvider GetAuthenticationProvider()
        {
            return session.GetAuthenticationProvider();
        }

        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 Dispose()
        {
            CheckSession();

            session.Lock();
            try
            {
                GetSpi().Dispose();
            }
            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)
                {
                    throw;
                }
                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 IAuthenticationProvider GetAuthenticationProvider()
        {
            return GetValue(AuthenticationProvider) as IAuthenticationProvider;
        }

        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 (IRepositoryInfo 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) && (result.List != 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>
    /// SPI interface.
    /// </summary>
    public interface ICmisSpi : IDisposable
    {
        void initialize(IBindingSession 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);
    }
}
