using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using SystemX.Common;
using SystemX.Common.Serialization;
using SystemX.Net.BaseProtocol;
using SystemX.Net.Schedule;

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

namespace SystemX.Net.MiddlewareUI.UIM.Protocol_Method
{
    public class USER_QUERY : ProtocolShell, IProtocol
    {
        public USER_QUERY(MainForm parent, int iPos, byte nLabel)
        : base(parent, iPos, nLabel)
        {
        }

        public override void ExecuteProtocol(BASE_PROTOCOL GET_PROTOCOL,
            BASE_PROTOCOL.PROTOCOL_CODE CODE,
            HEADER_PACKET getHeader,
            object objData)
        {
            QUERY_PACKET usPacket = (QUERY_PACKET)objData;

            string strGetQueryText = usPacket.objQueryText[0].Data;

            string[] stLstInfo = strGetQueryText.Split(';');

            //User Query Call
            if (stLstInfo[0].CompareTo("UserQueryCall") == 0)
            {
                try
                {
                    if (Parent_.GetUsetQueryInfo().bHasItem == false)
                        throw new Exception("User query no have item.");

                    var getQuery = Parent_.GetUsetQueryInfo().GetUserQueryInfo(stLstInfo[1]);

                    if (getQuery == null)
                        throw new Exception("Can't find [" + stLstInfo[1] + "] ID user query.");

                    //받은 파라미터 개수
                    int nParamNum = stLstInfo.Count() - 2;

                    string strQueryID = getQuery[0].Value.Item1;
                    string strQueryFrom = getQuery[0].Value.Item2;
                    string strMakeQueryText = getQuery[0].Value.Item3;
                    string strVarParam1 = getQuery[0].Value.Item4;

                    //From 부분 대체
                    int nParamPos = 0;
                    if (strQueryFrom.Length > 0)
                    {
                        if (strMakeQueryText.IndexOf("@$UseFrom@$") < 0)
                            throw new Exception("Access table argument format [@$UseFrom@$] syntax does not exist.");

                        string[] strLstQueryForms = strQueryFrom.Split(';');

                        foreach (string strFormParam in strLstQueryForms)
                        {
                            if (strMakeQueryText.IndexOf("@$UseFrom@$") < 0)
                                throw new Exception("The number of parameters and the number of argument types do not match.");

                            strMakeQueryText = strMakeQueryText.Replace("@$UseFrom@$[" + (nParamPos + 1).ToString() + "]", strFormParam);

                            nParamPos++;
                        }
                    }

                    //사용자 입력 쿼리 텍스트 파라미터 개수 파악
                    int nQueryParamNum = 0;
                    string strTemp = strMakeQueryText;
                    while (true)
                    {
                        if (strTemp.IndexOf("@$PARAM@$") >= 0)
                            nQueryParamNum++;
                        else
                            break;

                        strTemp = strTemp.Remove(strTemp.IndexOf("@$PARAM@$"), 12);
                    }

                    if(nParamNum != nQueryParamNum)
                        throw new Exception("The number of parameters does not match.");

                    //파라미터 정리
                    string[] lstParams = new string[nParamNum];
                    Array.Copy(stLstInfo, 2, lstParams, 0, nParamNum);

                    //파라미터 위치 값으로 대체
                    nParamPos = 0;
                    foreach (string strParamValue in lstParams)
                    {
                        strMakeQueryText = strMakeQueryText.Replace("@$PARAM@$[" + (nParamPos + 1).ToString() + "]", strParamValue);

                        nParamPos++;
                    }

                    Parent_.QueryProcess(strMakeQueryText, out ucSendByteInfo, strVarParam1);
                }
                catch (Exception e)
                {
                    MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + " User query process error! [" + e.Message + "] \r\n" + e.Message, ConsoleColor.Red, LogMessageLevel.FATAL);
                }
            }
        }
    }
}
