﻿/*
* 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 PortCMIS.Binding.Http;
using PortCMIS.Binding.Services;
using PortCMIS.Client;
using PortCMIS.Data;
using PortCMIS.Data.Extensions;
using PortCMIS.Exceptions;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Numerics;

namespace PortCMIS.Binding.Impl
{
    /// <summary>
    /// Binding layer implementation.
    /// </summary>
    internal class CmisBinding : ICmisBinding
    {
        private BindingSession session;
        private BindingRepositoryService repositoryServiceWrapper;

        private object bindingLock = new object();

        public CmisBinding(IDictionary<string, string> sessionParameters)
            : this(sessionParameters, null)
        {
        }

        public CmisBinding(IDictionary<string, string> sessionParameters, IAuthenticationProvider authenticationProvider)
        {
            if (sessionParameters == null)
            {
                throw new ArgumentNullException(nameof(sessionParameters));
            }

            if (!sessionParameters.ContainsKey(SessionParameter.BindingSpiClass))
            {
                throw new ArgumentException("Session parameters do not contain a SPI class name!");
            }

            // initialize session
            session = new BindingSession();
            foreach (KeyValuePair<string, string> kv in sessionParameters)
            {
                session.PutValue(kv.Key, kv.Value);
            }

            // set up authentication provider
            if (authenticationProvider == null)
            {
                string authenticationProviderClass;
                if (sessionParameters.TryGetValue(SessionParameter.AuthenticationProviderClass, out authenticationProviderClass))
                {
                    try
                    {
                        Type authProvType = Type.GetType(authenticationProviderClass);
                        authenticationProvider = (IAuthenticationProvider)Activator.CreateInstance(authProvType);
                        authenticationProvider.Session = session;
                        session.PutValue(BindingSession.AuthenticationProvider, authenticationProvider);
                    }
                    catch (Exception e)
                    {
                        throw new CmisRuntimeException("Could not load authentication 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 = PortCMIS.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();

            lock (bindingLock)
            {
                session.PutValue(BindingSession.RepositoryInfoCache, new RepositoryInfoCache(session));
                session.PutValue(BindingSession.TypeDefinitionCache, new TypeDefinitionCache(session));

                ICmisSpi spi = GetSpi();
                spi.ClearAllCaches();
            }
        }

        public void ClearRepositoryCache(string repositoryId)
        {
            CheckSession();

            if (repositoryId == null)
            {
                return;
            }

            lock (bindingLock)
            {
                RepositoryInfoCache repInfoCache = session.GetRepositoryInfoCache();
                repInfoCache.Remove(repositoryId);

                TypeDefinitionCache typeDefCache = session.GetTypeDefinitionCache();
                typeDefCache.Remove(repositoryId);

                ICmisSpi spi = GetSpi();
                spi.ClearRepositoryCache(repositoryId);
            }
        }

        public void Dispose()
        {
            CheckSession();

            lock (bindingLock)
            {
                GetSpi().Dispose();
                session = null;
            }
        }

        private void CheckSession()
        {
            if (session == null)
            {
                throw new InvalidOperationException("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.portcmis.bindings.repositoryInfoCache";
        public const string TypeDefinitionCache = "org.apache.chemistry.portcmis.bindings.typeDefintionCache";
        public const string AuthenticationProvider = "org.apache.chemistry.portcmis.bindings.authenticationProvider";
        public const string SpiObject = "org.apache.chemistry.portcmis.bindings.spi.object";
        public const string HttpInvokerObject = "org.apache.chemistry.portcmis.binding.httpinvoker.object";

        private readonly 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 (sessionLock)
            {
                if (data.TryGetValue(key, out result))
                {
                    return result;
                }
                else
                {
                    return defValue;
                }
            }
        }

        public int GetValue(string key, int defValue)
        {
            object value = GetValue(key);

            try
            {
                if (value is string)
                {
                    return Int32.Parse((string)value, CultureInfo.InvariantCulture);
                }
                else if (value is int)
                {
                    return (int)value;
                }
            }
            catch
            {
            }

            return defValue;
        }

        public bool GetValue(string key, bool defValue)
        {
            object value = GetValue(key);

            try
            {
                if (value is string)
                {
                    return Convert.ToBoolean((string)value, CultureInfo.InvariantCulture);
                }
                else if (value is bool)
                {
                    return (bool)value;
                }
            }
            catch
            {
            }

            return defValue;
        }

        public void PutValue(string key, object value)
        {
            lock (sessionLock)
            {
                data[key] = value;
            }
        }

        public void RemoveValue(string key)
        {
            lock (sessionLock)
            {
                data.Remove(key);
            }
        }

        public ICmisSpi GetSpi()
        {
            lock (sessionLock)
            {
                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;
            }
        }

        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 IHttpInvoker GetHttpInvoker()
        {
            lock (sessionLock)
            {
                IHttpInvoker invoker = GetValue(HttpInvokerObject) as IHttpInvoker;
                if (invoker != null)
                {
                    return invoker;
                }

                // ok, we have to create it...
                try
                {
                    object invokerObject;
                    if (data.TryGetValue(SessionParameter.HttpInvokerClass, out invokerObject))
                    {
                        string invokerClassName = invokerObject as string;
                        if (invokerClassName != null)
                        {
                            Type invokerClass = Type.GetType(invokerClassName);
                            invoker = (IHttpInvoker)Activator.CreateInstance(invokerClass);
                        }
                        else
                        {
                            throw new CmisRuntimeException("HTTP invoker class is not set!");
                        }
                    }
                    else
                    {
                        throw new CmisRuntimeException("HTTP invoker class is not set!");
                    }
                }
                catch (CmisBaseException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    throw new CmisRuntimeException("HTTP invoker cannot be initialized: " + e.Message, e);
                }

                // we have an invoker object -> put it into the session
                data[HttpInvokerObject] = invoker;

                return invoker;
            }
        }

        public override string ToString()
        {
            return data.ToString();
        }
    }

    /// <summary>
    /// Repository service proxy that caches repository infos and type definitions.
    /// </summary>
    internal class BindingRepositoryService : IRepositoryService
    {
        private readonly 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,
                BigInteger? maxItems, BigInteger? 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, BigInteger? 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;
        }

        public ITypeDefinition CreateType(string repositoryId, ITypeDefinition type, IExtensionsData extension)
        {
            ICmisSpi spi = session.GetSpi();
            return spi.GetRepositoryService().CreateType(repositoryId, type, extension);
        }

        public ITypeDefinition UpdateType(string repositoryId, ITypeDefinition type, IExtensionsData extension)
        {
            ICmisSpi spi = session.GetSpi();
            return spi.GetRepositoryService().UpdateType(repositoryId, type, extension);
        }

        public void DeleteType(string repositoryId, string typeId, IExtensionsData extension)
        {
            ICmisSpi spi = session.GetSpi();
            spi.GetRepositoryService().DeleteType(repositoryId, typeId, extension);
        }
    }
}
