using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO;
using System.Xml.Serialization;

namespace Tools.Config
{
    [Serializable]
    public class ConfigManager
    {
        #region Singlethon

        private static ConfigManager manager;
        public static ConfigManager Get()
        {
            if (manager == null)
                manager = new ConfigManager();

            FileInfo conf = new FileInfo(ConfigFile);

            if (conf.Exists)
            {
                //  Если после чтения конфига, он не перезаписывался
                if (conf.LastWriteTime == HasChanged)
                    return manager;

                try
                {
                    using (FileStream fs = File.OpenRead(conf.FullName))
                    {
                        //  Сохранить время последней записи конфига
                        HasChanged = conf.LastWriteTime;
                        manager.LoadXml(fs);
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            else
            {
                manager.InitDefaultVal();

                if (!conf.Directory.Exists)
                    Directory.CreateDirectory(conf.DirectoryName);

                using (FileStream fs = new FileStream(conf.FullName, FileMode.Create))
                {
                    manager.SaveXml().WriteTo(fs);
                }
                //  Сохранить время последней записи конфига
                HasChanged = conf.LastWriteTime;
            }

            return manager;
        }

        private ConfigManager() {}


        #endregion

        #region Data

        #region static

        //  Время последней записи конфига, чтобы не читать каждый раз файл
        private static DateTime HasChanged { set; get; }
        //Путь к корню файлов приложения | Задается при старте приложения | Все остальные пути идут относительно него
        public static string AppRootPath { set; get; }
        //Путь к файлу хранения конфигураций
        private static string Config_File = @"App_Data\Config\Config.xml";
        private static string ConfigFile
        {
            get
            {
                return AppRootPath + Config_File;
            }
        }

        #endregion
        
        public string SPARQL_Query_Endpoint { set; get; }
        public string SPARQL_Change_Endpoint { set; get; }
        public string ModeratorName { set; get; }
        public string ModeratorPassword { set; get; }


        #endregion

        #region Methods

        private void InitDefaultVal()
        {
            SPARQL_Query_Endpoint = "http://jena.denhome.keenetic.link/map/query";
            SPARQL_Change_Endpoint = "http://jena.denhome.keenetic.link/map/update";
            ModeratorName = "sstu";
            ModeratorPassword = "sstu";
        }

        private void Set(ConfigManager origin)
        {
            this.SPARQL_Query_Endpoint = origin.SPARQL_Query_Endpoint;
            this.SPARQL_Change_Endpoint = origin.SPARQL_Change_Endpoint;
            this.ModeratorName = origin.ModeratorName;
            this.ModeratorPassword = origin.ModeratorPassword;
        }

        public void LoadXml(Stream s)
        {
            XmlSerializer formatter = new XmlSerializer(typeof(ConfigManager));
            Set((ConfigManager)formatter.Deserialize(s));
            s.Position = 0;
        }
        public MemoryStream SaveXml()
        {
            MemoryStream res = new MemoryStream();

            XmlSerializer formatter = new XmlSerializer(typeof(ConfigManager));            
            formatter.Serialize(res, this);
            res.Position = 0;

            return res;
        }

        #endregion

    }
}
