using System;
using System.Collections.Generic;
using System.Web;
using System.Xml;
using Kreta.Framework;
using Kreta.Framework.Session;
using Kreta.KretaServer.ServerUtil;

namespace Kreta.KretaServer
{

    /// <summary>
    /// A Kréta kiszolgáló.
    /// </summary>
    public class KretaServer : SDAApplicationServer
    {
        public KretaServer(string configPath) : base(configPath)
        {
        }

        public KretaServer(XmlNode configNode) : base(configNode)
        {
        }

        public static new KretaServer Instance
        {
            get
            {
                return (KretaServer)SDAServer.Instance;
            }
        }

        public new KretaConfiguration Configuration
        {
            get
            {
                return (KretaConfiguration)base.Configuration;
            }
        }

        /// <summary>
        /// Intézményi azonosító kiszedése az URL-ből.
        /// </summary>
        /// <returns></returns>
        public override string GetOrganizationIdentifier()
        {
            var identifier = Configuration.TesztIntezmenyAzonosito;

            if (string.IsNullOrWhiteSpace(identifier))
            {
                try
                {
                    if (HttpContext.Current != null)
                    {
                        var request = HttpContext.Current.Request.Url.AbsoluteUri;
                        var requestArray = request.Replace("http://", null).Replace("https://", null).Split('.');
                        if (requestArray.Length > 1)
                        {
                            identifier = requestArray[0];
                        }
                    }
                }
                catch
                {
                }
            }

            return identifier;
        }

        public override string GetIntezmenyConnectionString(string intezmenyAzonosito)
        {
            return ConnectionManager.GetIntezmenyConnectionString(intezmenyAzonosito);
        }

        public override string GetSystemConnectionString(string intezmenyAzonosito)
        {
            return ConnectionManager.GetSystemConnectionString(intezmenyAzonosito);
        }

        public IEnumerable<string> GetOsszesIntezmeny()
        {
            return ConnectionManager.GetOsszesIntezmeny();
        }

        /// <summary>
        /// Karakterlánccá alakítja az objektumot.
        /// </summary>
        /// <returns>Az objektum leírása.</returns>
        public override string ToString()
        {
            if (Configuration == null)
            {
                return "KRETA server";
            }

            if (IsRunning)
            {
                return $"{Configuration.ServerName} server (running)";
            }

            return $"{Configuration.ServerName} server (stopped)";
        }

        protected override Configuration DoReadConfiguration(XmlNode configNode)
        {
            return new KretaConfiguration(configNode);
        }

        protected virtual void CreateConnectionManager()
        {
            ConnectionManager = new KretaConnectionManager();

            ConnectionManager.Initialize();
        }

        /// <summary>
        /// Elindítja a kiszolgálót.
        /// </summary> 
        protected override void DoStart()
        {
            base.DoStart();

            CreateConnectionManager();

            if (Configuration.SystemType == SystemType.Ismeretlen)
            {
                throw new Exception("Nincs beállítva a Kréta rendszer típusa a config-ban!");
            }

            //TODO: itt lehet finomhangolni a session naplozast amennyiben szukseges. adtam egy alapertelmezett implementaciot, ami csak signon/signoff esetben
            //naploz, hogy csokkentsem a dbhez fordulasok szamat. ha ettol pontosabb kep kell akkor be lehet kapcsolni az activate/deactivate lehetoseget is
            //Ha valakinek nem tetszik az altalam adott implementacio a naplora itt kotheti be a sajatjat.
            //glhf ^.^;
            this.SessionManager.SessionCreated += new SessionCreatedEventHandler(new Framework.Session.Instrumentation.SessionLogger().SessionCreated);
            this.SessionManager.SessionDeleted += new SessionDeletedEventHandler(new Framework.Session.Instrumentation.SessionLogger().SessionDeleted);
        }

        /// <summary>
        /// Leállítja a kiszolgálót.
        /// </summary>
        protected override void DoStop()
        {
            base.DoStop();
        }

        protected override SessionManager CreateSessionManager(Configuration configuration, Framework.Caching.CacheManager cacheManager)
        {
            return new SessionManager(configuration, cacheManager);
        }
    }
}