using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using SystemX.Common;
using SystemX.Common.Serialization;
using static SystemX.Net.DB.XDBConnManager;

namespace SystemX.Net.DB
{
    public class CMainConnInfo
    {
        public string Type { get; set; }
        public string IP { get; set; }
        public string Port { get; set; }
        public string ID { get; set; }
        public string PW { get; set; }
        public string SCHEMA { get; set; }
        public string MAC_ADDR { get; set; }
        public string SSPI { get; set; }

        public CMainConnInfo()
        {
            Type = string.Empty;
            IP = string.Empty;
            Port = string.Empty;
            ID = string.Empty;
            PW = string.Empty;
            SCHEMA = string.Empty;
            MAC_ADDR = string.Empty;
            SSPI = string.Empty;
        }
    }

    public class CShortTermConnInfo
    {
        public string Type { get; set; }
        public string IP { get; set; }
        public string Port { get; set; }
        public string ID { get; set; }
        public string PW { get; set; }
        public string SCHEMA { get; set; }
        public string MAC_ADDR { get; set; }
        public string SSPI { get; set; }

        public CShortTermConnInfo()
        {
            Type = string.Empty;
            IP = string.Empty;
            Port = string.Empty;
            ID = string.Empty;
            PW = string.Empty;
            SCHEMA = string.Empty;
            MAC_ADDR = string.Empty;
            SSPI = string.Empty;
        }
    }


    public class CLongTermConnInfo
    {
        public string Type { get; set; }
        public string IP { get; set; }
        public string Port { get; set; }
        public string ID { get; set; }
        public string PW { get; set; }
        public string SCHEMA { get; set; }
        public string MAC_ADDR { get; set; }
        public string SSPI { get; set; }

        public CLongTermConnInfo()
        {
            Type = string.Empty;
            IP = string.Empty;
            Port = string.Empty;
            ID = string.Empty;
            PW = string.Empty;
            SCHEMA = string.Empty;
            MAC_ADDR = string.Empty;
            SSPI = string.Empty;
        }
    }

    public class XDBConnInfo
    {
        public enum INFO_STRUCTURE
        {
            DBConnInfo,
            IP,
            Port,
            ID,
            PW,
            DB_CONN,
            MAC_ADDR,
            SSPI
        }

        public CMainConnInfo ConnMain;

        public CShortTermConnInfo ConnShortTerm;

        public CLongTermConnInfo ConnLongTerm;

        public XDBConnInfo()
        {
            ConnMain = new CMainConnInfo();
            ConnShortTerm = new CShortTermConnInfo();
            ConnLongTerm = new CLongTermConnInfo();
        }

        public bool ReadConfig(string strPath)
        {
            try
            {
                FileStream fs = new FileStream(strPath, FileMode.Open, FileAccess.Read);

                XmlDocument xmldoc = new XmlDocument();
                XmlNodeList nodeList;

                Type InfoType = typeof(XDBConnInfo);

                xmldoc.Load(fs);

                nodeList = xmldoc.GetElementsByTagName(INFO_STRUCTURE.DBConnInfo.ToString());

                XmlNode topNode = nodeList.Item(0);

                foreach (XmlNode node in topNode.ChildNodes)
                {
                    string strNodeName = node.Name;

                    if (strNodeName.CompareTo("MainConnInfo") == 0)
                    {
                        if (node.HasChildNodes == false)
                            throw new Exception("[MainConnInfo] Has no entries.");
                        if (node.ChildNodes.Count != 8)
                            throw new Exception("[MainConnInfo] Entries do not match.");

                        ConnMain.Type = node.ChildNodes[0].InnerText;
                        ConnMain.IP = node.ChildNodes[1].InnerText;
                        ConnMain.Port = node.ChildNodes[2].InnerText;
                        ConnMain.ID = node.ChildNodes[3].InnerText;
                        ConnMain.PW = node.ChildNodes[4].InnerText;
                        ConnMain.SCHEMA = node.ChildNodes[5].InnerText;
                        ConnMain.MAC_ADDR = node.ChildNodes[6].InnerText;
                        ConnMain.SSPI = node.ChildNodes[7].InnerText;
                    }
                    else if (strNodeName.CompareTo("ShortTermInfo") == 0)
                    {
                        if (node.HasChildNodes == false)
                            throw new Exception("[ShortTermInfo] Has no entries.");
                        if (node.ChildNodes.Count != 8)
                            throw new Exception("[ShortTermInfo] Entries do not match.");

                        ConnShortTerm.Type = node.ChildNodes[0].InnerText;
                        ConnShortTerm.IP = node.ChildNodes[1].InnerText;
                        ConnShortTerm.Port = node.ChildNodes[2].InnerText;
                        ConnShortTerm.ID = node.ChildNodes[3].InnerText;
                        ConnShortTerm.PW = node.ChildNodes[4].InnerText;
                        ConnShortTerm.SCHEMA = node.ChildNodes[5].InnerText;
                        ConnShortTerm.MAC_ADDR = node.ChildNodes[6].InnerText;
                        ConnShortTerm.SSPI = node.ChildNodes[7].InnerText;
                    }
                    else if(strNodeName.CompareTo("LongTermInfo") == 0)
                    {
                        if (node.HasChildNodes == false)
                            throw new Exception("[LongTermInfo] Has no entries.");
                        if (node.ChildNodes.Count != 8)
                            throw new Exception("[LongTermInfo] Entries do not match.");

                        ConnLongTerm.Type = node.ChildNodes[0].InnerText;
                        ConnLongTerm.IP = node.ChildNodes[1].InnerText;
                        ConnLongTerm.Port = node.ChildNodes[2].InnerText;
                        ConnLongTerm.ID = node.ChildNodes[3].InnerText;
                        ConnLongTerm.PW = node.ChildNodes[4].InnerText;
                        ConnLongTerm.SCHEMA = node.ChildNodes[5].InnerText;
                        ConnLongTerm.MAC_ADDR = node.ChildNodes[6].InnerText;
                        ConnLongTerm.SSPI = node.ChildNodes[7].InnerText;
                    }
                    /*
                    else
                    {
                        PropertyInfo propFound = InfoType.GetProperty(strNodeName);

                        if (propFound != null)
                            propFound.SetValue(this, node.InnerText);
                    }
                    */
                }

                fs.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"DB Connection Info. Reading Error : {ex.Message}");

                return false;
            }

            return true;
        }

        public string GetConnectionStatement(eDbType eType, eConnCategory eConn)
        {
            string strStatement = string.Empty;

            bool bSSPI = true;

            string IP_ADDRESS = string.Empty;
            string PORT_NUMBER = string.Empty;
            string CONN_SCHEMA = string.Empty;
            string IDENTIFIER = string.Empty;
            string PASSWORD = string.Empty;

            switch (eConn)
            {
                case eConnCategory.Main:
                    {
                        if (ConnMain.SSPI.IndexOf("False") >= 0) bSSPI = false;

                        IP_ADDRESS = ConnMain.IP;
                        PORT_NUMBER = ConnMain.Port;
                        CONN_SCHEMA = ConnMain.SCHEMA;
                        IDENTIFIER = ConnMain.ID;
                        PASSWORD = ConnMain.PW;
                    }
                    break;
                case eConnCategory.ShortTerm:
                    {
                        if (ConnShortTerm.SSPI.IndexOf("False") >= 0) bSSPI = false;

                        IP_ADDRESS = ConnShortTerm.IP;
                        PORT_NUMBER = ConnShortTerm.Port;
                        CONN_SCHEMA = ConnShortTerm.SCHEMA;
                        IDENTIFIER = ConnShortTerm.ID;
                        PASSWORD = ConnShortTerm.PW;
                    }
                    break;
                case eConnCategory.LongTerm:
                    {
                        if (ConnLongTerm.SSPI.IndexOf("False") >= 0) bSSPI = false;

                        IP_ADDRESS = ConnLongTerm.IP;
                        PORT_NUMBER = ConnLongTerm.Port;
                        CONN_SCHEMA = ConnLongTerm.SCHEMA;
                        IDENTIFIER = ConnLongTerm.ID;
                        PASSWORD = ConnLongTerm.PW;
                    }
                    break;
            }

            switch (eType)
            {
                case eDbType.MS_SQL:
                    if (bSSPI == false)
                        strStatement = $"Data Source = {IP_ADDRESS},{PORT_NUMBER}; Initial Catalog = {CONN_SCHEMA}; User ID = {IDENTIFIER}; Password = {PASSWORD}; MultipleActiveResultSets=True;";
                    else
                        strStatement = $"Data Source = localhost; Initial Catalog = {CONN_SCHEMA}; Integrated Security = SSPI; MultipleActiveResultSets=True;";
                    break;
                default:
                    break;
            }

            return strStatement;
        }
    }
}
