using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;

using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT.XML;

using static C4IT.Logging.cLogManager;

namespace C4IT.DataHistoryProvider
{
    public class cConfigCacheEntry
    {
        public string FullPath { get; set; } = null;
        public DateTime TimeStamp { get; set; }
        public string Content { get; set; }

        public static cConfigCacheEntry GetCacheEntry(enumFasdConfigurationType configType)
        {
            var output = new cConfigCacheEntry();

            if (output.IsValidConfig(configType) && !string.IsNullOrEmpty(output.FullPath))
            {
                output.TimeStamp = File.GetLastWriteTimeUtc(output.FullPath);
                output.Content = File.ReadAllText(output.FullPath);
                return output;
            }
            return null;
        }

        public bool CheckIfNewerExists()
        {
            try
            {
                if (string.IsNullOrEmpty(FullPath))
                    return false;

                if (File.GetLastWriteTimeUtc(FullPath) > TimeStamp)
                    return true;
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return false;
        }

        private bool IsValidConfig(enumFasdConfigurationType configType)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }

            try
            {
                var RetVal = cFasdBaseConfig.GetConfigByType(configType);
                if (RetVal != null && RetVal.IsValid)
                {
                    FullPath = RetVal.FilePath;
                    return true;
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                if (CM != null) LogMethodEnd(CM);
            }
            return false;
        }
    }

    public static class cConfigCache
    {
        private static Dictionary<enumFasdConfigurationType, cConfigCacheEntry> Cache = new Dictionary<enumFasdConfigurationType, cConfigCacheEntry>();

        public static cConfigCacheEntry Get(enumFasdConfigurationType configType)
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
            try
            {
                if (Cache.TryGetValue(configType, out var result))
                {
                    if (!result.CheckIfNewerExists())
                        return result;
                }

                result = cConfigCacheEntry.GetCacheEntry(configType);

                if (result != null)
                    Cache[configType] = result;

                return result;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                if (CM != null) LogMethodEnd(CM);
            }

            return null;
        }

        public static void Initialize()
        {
            MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
            try
            {
                var _lst = Enum.GetValues(typeof(enumFasdConfigurationType)).Cast<enumFasdConfigurationType>();
                foreach (var _item in _lst)
                {
                    if (_item != enumFasdConfigurationType.unknown)
                        Get(_item);
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                if (CM != null) LogMethodEnd(CM);
            }
        }
    }
}