using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using SystemX.Net.BaseProtocol;
using SystemX.Net.DB;

using CpTesterPlatform.CpLogUtil;

using static SystemX.Net.Platform.Common.Util.LogMessage;

namespace SystemX.Common.Log.SIA
{
    /// <summary>
    /// Query Base Infomation
    /// </summary>
    /// 
    public class LogProcessInfo_SIA
    {
        public bool READ_INFO_STATE { set; get; }

        private string strInfoFilePos;

        //TestID, TableName
        private Dictionary<string, Tuple<int, string>> dicBaseIDInfo;
        //TestID, DetailLogUse
        private Dictionary<string, bool> dicDetailInfo;
        //KEY - STEP, Name, UpdateTableName, ToField
        private Dictionary<int, Tuple<string, bool, string, int, string, string, string>> dicSubExtrctionInfo;

        public bool USE_TABLE_DATA_DELETE_MANAGER { internal set; get; }

        //KEY - TableName, USE
        private Dictionary<string, bool> dicTableDataDeleteList;
        //KEY - No, USE, TableName, Set Date
        private Dictionary<int, Tuple<bool, string, int>> dicTableDataDeleteManager;

        public LogProcessInfo_SIA(string strGetInfoPath) 
        {
            strInfoFilePos = strGetInfoPath;

            dicBaseIDInfo = new Dictionary<string, Tuple<int, string>>();
            dicDetailInfo = new Dictionary<string, bool>();
            dicSubExtrctionInfo = new Dictionary<int, Tuple<string, bool, string, int, string, string, string>>();
            //
            dicTableDataDeleteList = new Dictionary<string, bool>();
            dicTableDataDeleteManager = new Dictionary<int, Tuple<bool, string, int>>();
        }
        public string GetSaveTableName(string strTestID)
        {
            if (dicBaseIDInfo.Keys.Contains(strTestID))
            {
                return dicBaseIDInfo[strTestID].Item2;
            }
            else
                return "";
        }
        public bool GetSaveDetailTable(string strTestID)
        {
            if (dicDetailInfo.Keys.Contains(strTestID))
                return dicDetailInfo[strTestID];
            else
                return false;
        }
        public List<KeyValuePair<int, Tuple<string, bool, string, int, string, string, string>>> GetExtractInfo(string strTestID)
        {
            if (dicBaseIDInfo.Keys.Contains(strTestID))
                return dicSubExtrctionInfo.ToList().FindAll(x => x.Value.Item1 == strTestID);
            else
                return null;
        }
        public List<KeyValuePair<int, Tuple<bool, string, int>>> GeManageInfo()
        {
            return dicTableDataDeleteManager.ToList();
        }

        public bool Load()
        {
            READ_INFO_STATE = true;

            int iSetPos = 0;
            try
            {
                XDocument xDoc = XDocument.Load(strInfoFilePos);
                var xElement = xDoc.Element("ROOT");

                if (xElement != null)
                {
                    var ListGetElement = xElement.Elements("TableDataDeleteManager").ToList();

                    foreach (var getXElement in ListGetElement)
                    {
                        USE_TABLE_DATA_DELETE_MANAGER = Convert.ToBoolean(getXElement.Attribute("USE").Value);

                        if (getXElement.Elements().ToList().Count > 0)
                        {
                            iSetPos = 0;
                            for (int i = 0; i < getXElement.Elements().ToList().Count; i++)
                            {
                                int iGetDateDiff = 0;
                                if (int.TryParse(getXElement.Element("Management" + (i + 1).ToString()).Attribute("DateDifference").Value.ToString(), out iGetDateDiff))
                                {
                                    dicTableDataDeleteList.Add(getXElement.Element("Management" + (i + 1).ToString()).Attribute("TableName").Value,
                                        Convert.ToBoolean(getXElement.Element("Management" + (i + 1).ToString()).Attribute("USE").Value));

                                    dicTableDataDeleteManager.Add(iSetPos++,
                                    new Tuple<bool, string, int>(
                                        Convert.ToBoolean(getXElement.Element("Management" + (i + 1).ToString()).Attribute("USE").Value),
                                        getXElement.Element("Management" + (i + 1).ToString()).Attribute("TableName").Value,
                                        iGetDateDiff));
                                }
                                else
                                    throw new Exception("DateDifference value error.");
                            }
                        }
                    }

                    ListGetElement = xElement.Elements("QueryInfo").ToList();

                    foreach (var getXElement in ListGetElement)
                    {
                        string strBaseID = getXElement.Attribute("ID").Value;

                        bool bGetDetailSelect = false;

                        int iGetProcNo = int.Parse(getXElement.Attribute("ProcNo").Value);
                        dicBaseIDInfo.Add(strBaseID, new Tuple<int, string>(iGetProcNo, getXElement.Attribute("Table").Value));
                        dicDetailInfo.Add(strBaseID, bool.TryParse(getXElement.Attribute("DetailProcess").Value, out bGetDetailSelect) == true ? bGetDetailSelect : false);

                        if (getXElement.Elements().ToList().Count > 0)
                        {
                            iSetPos = 0;
                            for (int i = 0; i < getXElement.Elements().ToList().Count; i++)
                            {
                                int iGetStep = 0;
                                if (int.TryParse(getXElement.Element("ExtractionInfo" + (i + 1).ToString()).Attribute("Step").Value.ToString(), out iGetStep))
                                {
                                    string strUpdateTable = getXElement.Element("ExtractionInfo" + (i + 1).ToString()).Attribute("UpdateTableName").Value;

                                    bool bUpdateTableDiff = dicSubExtrctionInfo.ToList().FindAll(x => x.Value.Item1 == strBaseID).All(x => x.Value.Item6 == strUpdateTable);

                                    if (bUpdateTableDiff == false)
                                        throw new Exception();

                                    dicSubExtrctionInfo.Add(iSetPos++,
                                    new Tuple<string, bool, string, int, string, string, string>(
                                        strBaseID,
                                        Convert.ToBoolean(getXElement.Element("ExtractionInfo" + (i + 1).ToString()).Attribute("MO_Find").Value),
                                        getXElement.Element("ExtractionInfo" + (i + 1).ToString()).Attribute("MO").Value,
                                        iGetStep,
                                        getXElement.Element("ExtractionInfo" + (i + 1).ToString()).Attribute("Name").Value,
                                        getXElement.Element("ExtractionInfo" + (i + 1).ToString()).Attribute("UpdateTableName").Value,
                                        getXElement.Element("ExtractionInfo" + (i + 1).ToString()).Attribute("ToField").Value));
                                }
                                else
                                    throw new Exception("Step value error.");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                READ_INFO_STATE = false;

                MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"LogProcessInfo read failed. [SystemX.Common.Protocol.Log.SIA : LogProcessInfo_SIA.Load]\r\n" + ex.Message, ConsoleColor.Yellow, LogMessageLevel.DEBUG);
            }

            return READ_INFO_STATE;
        }
    }
}
