using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;
using static iMESCore.Base.iMESComSubroutine;
using static iMESCore.Base.iMESComXML;

namespace MESws
{
    internal class DataExchange
    {
        /// <summary>
        /// 2020/04/24 雋辰,XML string convert DataSet
        /// </summary>
        /// <param name="OutXml"></param>
        /// <param name="columns">資料表需求欄位</param>
        /// <returns></returns>
        public static DataSet XmlString2DataSet(string OutXml, string[] columns = null)
        {

            DataSet result = null;
            StringReader tmpStringReader; // 將字串轉換成可讀入DataSet的物件
            var XmlDoc = new XmlDocument();
            XmlElement xElement_Schema = null;
            string FirstChildName = "";
            string XmlSchema = "";
            string XmlData = ""; // 儲存取回之資料
            var aryException = new List<ArrayList>();  // Exception

            try
            {
                using (var dsReturn = new DataSet())
                {
                    // 利用XmlDoc物件處理ReturnValue 
                    XmlDoc.LoadXml(OutXml);

                    // 找出第一個節點
                    FirstChildName = XmlDoc.FirstChild.Name;

                    // 取出Schema
                    XmlSchema = XmlDoc.FirstChild.SelectSingleNode("schema").InnerXml;
                    if (!string.IsNullOrEmpty(XmlSchema))
                    {
                        // 將XML讀入String Reader object中,因為Dataset讀入XML時必須透過String Reader物件
                        tmpStringReader = new StringReader(XmlSchema);
                        dsReturn.ReadXmlSchema(tmpStringReader);
                        tmpStringReader.Close();
                    }

                    // 取出Data
                    XmlData = XmlDoc.FirstChild.SelectSingleNode("value").InnerXml;
                    if (!string.IsNullOrEmpty(XmlData))
                    {
                        tmpStringReader = new StringReader(XmlData);
                        dsReturn.ReadXml(tmpStringReader, XmlReadMode.InferSchema);
                        tmpStringReader.Close();
                    }

                    // 欄位轉大寫
                    ColumnName_ToUpper(dsReturn);

                    // 只取需要的欄位
                    DataSet ds = (DataSet)Specify_Field(dsReturn, new List<string[]>() { columns });
                    result = ds;

                }
            }
            catch (Exception ex)
            {
                throw;
            }

            return result;

        }

        /// <summary>
        /// 2020/05/28 雋辰,XML string convert JObject , 為了因應xml有多個根節點(多個類型的資料)
        /// </summary>
        /// <param name="OutXml"></param>
        /// <param name="columns">資料表需求欄位</param>
        /// <returns></returns>
        public static JObject XmlString2JsonObj(string OutXml, string[] columns = null)
        {

            var result = new JObject();
            JToken tempToken;

            var XmlDoc = new XmlDocument();

            string XmlSchema = "";
            string XmlData = ""; // 儲存取回之資料

            string rootName = "tempRoot";

            string key = "";
            string tempKey;
            bool firstDataSet = true;

            try
            {
                // 利用XmlDoc物件處理ReturnValue 
                XmlDoc.LoadXml(string.Format("<{0}>{1}</{0}>", rootName, OutXml));

                var root = XmlDoc.SelectSingleNode(rootName);

                foreach (XmlNode node in root.ChildNodes)
                {
                    if (!(node.SelectSingleNode("name") == null) && !(node.SelectSingleNode("type") == null) && !(node.SelectSingleNode("value") == null))
                    {

                        if (node.SelectSingleNode("type").InnerXml.ToUpper() == "DATASET")
                        {

                            if (node.SelectSingleNode("schema") == null)
                                continue;
                            XmlSchema = node.SelectSingleNode("schema").InnerXml;
                            if (string.IsNullOrEmpty(XmlSchema))
                                continue;

                            var ds = new DataSet();
                            using (var tmpStringReader = new StringReader(XmlSchema))
                            {
                                ds.ReadXmlSchema(tmpStringReader);
                            }

                            DataSet dsSpecify;
                            if (firstDataSet)
                            {
                                dsSpecify = (DataSet)Specify_Field(ds, new List<string[]>() { columns });
                                firstDataSet = false;
                            }
                            else
                            {
                                dsSpecify = ds;
                            }

                            XmlData = node.SelectSingleNode("value").InnerXml;
                            if (!string.IsNullOrEmpty(XmlData))
                            {
                                using (var tmpStringReader = new StringReader(XmlData))
                                {
                                    dsSpecify.ReadXml(tmpStringReader, XmlReadMode.Auto);
                                }
                            }
                            ColumnName_ToUpper(dsSpecify);

                            foreach (DataTable dt in dsSpecify.Tables)
                            {
                                key = dt.TableName;

                                tempKey = key;
                                tempToken = result[key];
                                if (!(tempToken == null))
                                {
                                    int index = 2;
                                    do
                                    {
                                        tempKey = string.Format("{0}({1})", key, index);
                                        tempToken = result[tempKey];
                                        index += 1;
                                    }
                                    while (tempToken != null);
                                }

                                result.Add(tempKey, JToken.Parse(JsonConvert.SerializeObject(dt)));
                            }
                        }

                        else
                        {
                            key = node.SelectSingleNode("name").InnerXml;

                            if (string.IsNullOrEmpty(key))
                                continue;

                            tempKey = key;
                            tempToken = result[key];
                            if (!(tempToken == null))
                            {
                                int index = 2;
                                do
                                {
                                    tempKey = string.Format("{0}({1})", key, index);
                                    tempToken = result[tempKey];
                                    index += 1;
                                }
                                while (tempToken != null);
                            }

                            result.Add(tempKey, node.SelectSingleNode("value").InnerXml);
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            return result;

        }

        /// <summary>
        /// 2020/07/31 雋辰,XML string convert JObject for wsSTD
        /// </summary>
        /// <param name="OutXml"></param>
        /// <param name="columns">資料表需求欄位</param>
        /// <returns></returns>
        public static JObject XmlString2JsonObj_wsSTD(ref string stack, string OutXml, string[] columns = null, string language = "", string resourceDir = "Resource")
        {

            var result = new JObject();
            JToken tempToken;

            var XmlDoc = new XmlDocument();

            string XmlSchema = "";
            string XmlData = ""; // 儲存取回之資料

            string rootName = "returnvalue";

            string key = "";
            string tempKey;
            bool firstDataSet = true;

            try
            {
                // 利用XmlDoc物件處理ReturnValue 
                XmlDoc.LoadXml(OutXml);

                if (!chkExecutionSuccess(XmlDoc))
                {
                    string exCode = GetExceptionCode(XmlDoc);
                    string exMsg = GetExceptionSysMsg(XmlDoc);
                    string exStack = GetExceptionStack(XmlDoc);
                    stack = exStack;
                    var iex = new iMESException.MESException(exCode, exMsg);
                    throw new System.Reflection.TargetInvocationException(exMsg, iex);
                }

                var response = XmlDoc.SelectSingleNode("response");
                if (response == null)
                    throw new iMESException.MESException("0000-200091", "OutXML [%Format Error%]");

                // 20210408 13871,執行結果success/fail
                var resultTag = response.SelectSingleNode("result");
                if (!(resultTag == null))
                    result.Add("ReturnValue", resultTag.InnerText);

                // 20210408 13871,額外訊息message tag下的資訊
                // <message>
                // <note>
                // <mcode>
                // <mtype>
                // <mmsg>
                // </note>
                // <note>
                // <mcode>
                // <mtype>
                // <mmsg>
                // </note>
                var messageTag = response.SelectSingleNode("message");
                if (!(messageTag == null))
                {
                    var dtMessage = new DataTable();
                    dtMessage.Columns.Add("MCODE");
                    dtMessage.Columns.Add("MTYPE");
                    dtMessage.Columns.Add("MMSG");
                    var notes = messageTag.SelectNodes("note");

                    for (int i = 0, loopTo = notes.Count - 1; i <= loopTo; i++)
                    {
                        var drTmp = dtMessage.NewRow();
                        if (!(notes.Item(i).SelectSingleNode("mcode") == null))
                        {
                            drTmp["MCODE"] = notes.Item(i).SelectSingleNode("mcode").InnerText;
                        }
                        if (!(notes.Item(i).SelectSingleNode("mtype") == null))
                        {
                            drTmp["MTYPE"] = notes.Item(i).SelectSingleNode("mtype").InnerText;
                        }
                        if (!(notes.Item(i).SelectSingleNode("mmsg") == null))
                        {
                            drTmp["MMSG"] = TranslateMsg(notes.Item(i).SelectSingleNode("mmsg").InnerText, language, resourceDir);
                        }
                        dtMessage.Rows.Add(drTmp);
                    }

                    result.Add("RETURNMESSAGE", JToken.Parse(JsonConvert.SerializeObject(dtMessage)));
                }

                // 20210408 13871,回傳的結果於returnvalue tag下的資訊
                var root = response.SelectSingleNode(rootName);
                if (!(root == null))
                {
                    foreach (XmlNode node in root.ChildNodes)
                    {
                        if (!(node.SelectSingleNode("name") == null) && !(node.SelectSingleNode("type") == null) && !(node.SelectSingleNode("value") == null))
                        {
                            if (node.SelectSingleNode("type").InnerXml.ToUpper() == "DATASET")
                            {

                                if (node.SelectSingleNode("schema") == null)
                                    continue;
                                XmlSchema = node.SelectSingleNode("schema").InnerXml;
                                if (string.IsNullOrEmpty(XmlSchema))
                                    continue;

                                var ds = new DataSet();
                                using (var tmpStringReader = new StringReader(XmlSchema))
                                {
                                    ds.ReadXmlSchema(tmpStringReader);
                                }

                                DataSet dsSpecify;
                                if (firstDataSet)
                                {
                                    dsSpecify = (DataSet)Specify_Field(ds, new List<string[]>() { columns });
                                    firstDataSet = false;
                                }
                                else
                                {
                                    dsSpecify = ds;
                                }

                                XmlData = node.SelectSingleNode("value").InnerXml;
                                if (!string.IsNullOrEmpty(XmlData))
                                {
                                    using (var tmpStringReader = new StringReader(XmlData))
                                    {
                                        dsSpecify.ReadXml(tmpStringReader, XmlReadMode.Auto);
                                    }
                                }
                                ColumnName_ToUpper(dsSpecify);

                                foreach (DataTable dt in dsSpecify.Tables)
                                {
                                    key = dt.TableName;

                                    tempKey = key;
                                    tempToken = result[key];
                                    if (!(tempToken == null))
                                    {
                                        int index = 2;
                                        do
                                        {
                                            tempKey = string.Format("{0}({1})", key, index);
                                            tempToken = result[tempKey];
                                            index += 1;
                                        }
                                        while (tempToken != null);
                                    }

                                    result.Add(tempKey, JToken.Parse(JsonConvert.SerializeObject(dt)));
                                }
                            }

                            else
                            {
                                key = node.SelectSingleNode("name").InnerXml;

                                if (string.IsNullOrEmpty(key))
                                    continue;

                                tempKey = key;
                                tempToken = result[key];
                                if (!(tempToken == null))
                                {
                                    int index = 2;
                                    do
                                    {
                                        tempKey = string.Format("{0}({1})", key, index);
                                        tempToken = result[tempKey];
                                        index += 1;
                                    }
                                    while (tempToken != null);
                                }

                                result.Add(tempKey, node.SelectSingleNode("value").InnerXml);
                            }

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            return result;

        }

        /// <summary>
        /// 2020/04/24 雋辰,輸出指定欄位資料表
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public static object Specify_Field(DataSet ds, List<string[]> columns)
        {
            var result = new DataSet();
            if (!(ds == null))
            {
                for (int i = 0, loopTo = ds.Tables.Count - 1; i <= loopTo; i++)
                {
                    if (!(columns == null) && columns.Count > i && !(columns[i] == null))
                    {
                        result.Tables.Add(ds.Tables[i].DefaultView.ToTable(false, columns[i]));
                    }
                    else
                    {
                        result.Tables.Add(ds.Tables[i].Copy());
                    }
                }
            }

            return result;

        }

        /// <summary>
        /// 2020/04/24 雋辰,欄位名稱轉大寫
        /// </summary>
        /// <param name="ds"></param>
        public static void ColumnName_ToUpper(DataSet ds)
        {
            if (!(ds == null))
            {
                foreach (DataTable dt in ds.Tables)
                {
                    foreach (DataColumn dc in dt.Columns)
                        dc.ColumnName = dc.ColumnName.ToUpper();
                }
            }
        }

        /// <summary>
        /// 2020/09/28 雋辰,欄位名稱轉大寫
        /// </summary>
        /// <param name="dt"></param>
        public static void ColumnName_ToUpper(DataTable dt)
        {
            if (!(dt == null))
            {
                foreach (DataColumn dc in dt.Columns)
                    dc.ColumnName = dc.ColumnName.ToUpper();
            }
        }

        /// <summary>
        /// 2020/06/10 雋辰,處理Transfer
        /// </summary>
        /// <param name="listTransfer"></param>
        /// <param name="val">call function result</param>
        /// <param name="transferGlobal"></param>
        /// <param name="transferSingle"></param>
        public static void ProcessTransfer(List<JToken> listTransfer, object val, ref Dictionary<string, object> transferGlobal, ref Dictionary<string, object> transferSingle)
        {

            string strTransferLevel;
            string strTransferParName;
            string strTransferValue;
            Dictionary<string, object> addTransfer;

            if (listTransfer == null || listTransfer.Count <= 0 || transferGlobal == null || transferSingle == null)
                return;

            // 處理傳遞引數
            foreach (JToken item in listTransfer)
            {
                var dicTemp = JsonConvert.DeserializeObject<Dictionary<string, string>>(item.ToString());
                var dicProp = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
                foreach (string key in dicTemp.Keys)
                    dicProp[key] = dicTemp[key];

                if (!dicProp.ContainsKey("level") || !dicProp.ContainsKey("value") || !dicProp.ContainsKey("parname"))
                    continue;
                strTransferLevel = dicProp["level"].ToUpper();
                strTransferParName = dicProp["parname"];
                strTransferValue = dicProp["value"].ToUpper();

                if (strTransferLevel == "G")
                {
                    addTransfer = transferGlobal;
                }
                else if (strTransferLevel == "S")
                {
                    addTransfer = transferSingle;
                }
                else
                {
                    continue;
                }

                if (addTransfer == null)
                    continue;

                if (val.GetType().Equals(typeof(DataSet)))
                {
                    DataSet ds = val as DataSet;
                    if (strTransferValue == "M_RESULT")
                    {
                        addTransfer[strTransferParName] = ds.Tables[0];
                    }
                    else if (ds.Tables[0].Columns.Contains(strTransferValue))
                        addTransfer[strTransferParName] = ds.Tables[0].Rows.Count > 0 ? ds.Tables[0].Rows[0][strTransferValue] : "";
                }
                else if (val.GetType().Equals(typeof(JObject)))
                {
                    JObject jObj = val as JObject;
                    var list = (from prop in jObj.Properties()
                                select prop.Name.ToUpper()).ToList();

                    if (strTransferValue == "M_RESULT")
                        strTransferValue = "RETURNVALUE";
                    if (list.Contains(strTransferValue))
                    {
                        foreach (JProperty p in jObj.Properties())
                        {
                            if (p.Name.ToUpper() == strTransferValue)
                            {
                                if (p.Value.GetType().Equals(typeof(JArray)))
                                {
                                    var ds = JsonConvert.DeserializeObject<DataSet>("{" + p.ToString() + "}");
                                    addTransfer[strTransferParName] = ds.Tables[0];
                                    break;
                                }
                                else
                                {
                                    addTransfer[strTransferParName] = p.Value.ToString();
                                    break;
                                }
                            }
                        }
                    }
                }
                else if (strTransferValue == "M_RESULT")
                    addTransfer[strTransferParName] = val;
            }
        }

        /// <summary>
        /// 2020/07/31 雋辰,處理Transfer
        /// </summary>
        /// <param name="listTransfer"></param>
        /// <param name="val">call function result</param>
        /// <param name="transferGlobal"></param>
        /// <param name="transferSingle"></param>
        public static void ProcessTransfer_Load(List<JToken> listTransfer, JObject jObj, ref Dictionary<string, object> transferGlobal, ref Dictionary<string, object> transferSingle)
        {

            string strTransferLevel;
            string strTransferParName;
            string strTransferValue;
            Dictionary<string, object> addTransfer;

            if (!(listTransfer == null) && !(transferGlobal == null) && !(transferSingle == null))
            {
                foreach (JToken item in listTransfer)
                {
                    var dicTemp = JsonConvert.DeserializeObject<Dictionary<string, string>>(item.ToString());
                    var dicProp = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
                    foreach (string key in dicTemp.Keys)
                        dicProp[key] = dicTemp[key];

                    if (!dicProp.ContainsKey("level") || !dicProp.ContainsKey("value") || !dicProp.ContainsKey("parname"))
                        continue;
                    strTransferLevel = dicProp["level"].ToUpper();
                    strTransferParName = dicProp["parname"];
                    strTransferValue = dicProp["value"].ToUpper();

                    if (strTransferLevel == "G")
                    {
                        addTransfer = transferGlobal;
                    }
                    else if (strTransferLevel == "S")
                    {
                        addTransfer = transferSingle;
                    }
                    else
                    {
                        continue;
                    }

                    if (addTransfer == null)
                        continue;

                    if (strTransferValue == "M_RESULT")
                    {
                        foreach (JProperty subResult in jObj.Children())
                        {
                            if (subResult.ToString().Contains("[") && subResult.ToString().Contains("]"))
                            {
                                var ds = JsonConvert.DeserializeObject<DataSet>("{" + subResult.ToString() + "}");
                                addTransfer[strTransferParName] = ds.Tables[0];
                                break;
                            }
                        }
                    }
                    else
                    {
                        foreach (JProperty subResult in jObj.Children())
                        {
                            // 沒有想到合適的方式區分一般值與DataSet
                            if (subResult.Value.GetType().Equals(typeof(JArray)))
                            {
                                var ds = JsonConvert.DeserializeObject<DataSet>("{" + subResult.ToString() + "}");
                                if (ds.Tables[0].Columns.Contains(strTransferValue))
                                {
                                    addTransfer[strTransferParName] = ds.Tables[0].Rows.Count > 0 ? ds.Tables[0].Rows[0][strTransferValue] : "";
                                    break;
                                }
                            }
                            else if (strTransferValue == subResult.Name.ToUpper())
                            {
                                addTransfer[strTransferParName] = subResult.Value.ToString();
                                break;
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 2020/07/31,處理Ref類型參數
        /// </summary>
        /// <param name="jObj"></param>
        /// <param name="pars"></param>
        /// <param name="index"></param>
        public static void PorcessRef(ref JObject jObj, object[] pars, Dictionary<short, string> index)
        {

            if (index == null || pars == null)
                return;


            for (int i = 0, loopTo = pars.Length - 1; i <= loopTo; i++)
            {
                try
                {
                    if (pars[i] == null)
                        continue;

                    if (ReferenceEquals(pars[i].GetType(), typeof(DataSet)))
                    {
                        DataSet dsTemp = pars[i] as DataSet;
                        ColumnName_ToUpper(dsTemp);
                        pars[i] = dsTemp;
                    }
                    else if (ReferenceEquals(pars[i].GetType(), typeof(DataTable)))
                    {
                        DataTable dtTemp = pars[i] as DataTable;
                        ColumnName_ToUpper(dtTemp);
                        pars[i] = dtTemp;
                    }
                }
                catch (Exception ex)
                {
                    Log.WriteLog("PorcessRef fail:DataTable Upper" + i, iMESLog.iMESLogLevel.Warn, ex);
                }
            }

            string key = "";
            foreach (short i in index.Keys)
            {
                try
                {
                    key = "";
                    key = index[i];
                    var p = jObj.Property(index[i]);

                    if (!(p == null))
                        continue;

                    jObj.Add(key, Newtonsoft.Json.Linq.JToken.Parse(JsonConvert.SerializeObject(pars[i])));
                }
                catch (Exception ex)
                {
                    Log.WriteLog("PorcessRef fail:" + key, iMESLog.iMESLogLevel.Warn, ex);
                }
            }
        }

        /// <summary>
        /// 2020/07/28 雋辰,parameter convert to XML
        /// </summary>
        /// <param name="dic">parameter</param>
        /// <returns></returns>
        public static string Parameter2XML(Dictionary<string, object> dic, Dictionary<string, object> t_global = null, Dictionary<string, object> t_single = null)
        {
            string result = "";
            try
            {
                foreach (string key in dic.Keys)
                {
                    try
                    {
                        if (dic[key] == null)
                            continue;

                        if (key.ToLower() == "additional")
                        {
                            result += dic[key];
                        }
                        else if (dic[key].GetType() == typeof(Newtonsoft.Json.Linq.JArray))
                        {
                            try
                            {
                                // 20210513 13871,MantisBT:0092632,DataTable轉型傳入自定義JsonConvert方式,排除浮點數被轉成整數問題
                                JsonSerializerSettings settings = new JsonSerializerSettings() { Converters = new[] { new TypeInferringDataTableConverter() } };
                                DataTable dt = JsonConvert.DeserializeObject<DataTable>(dic[key].ToString(), settings);
                                string tmpXml = "";
                                string tmpVal = "";
                                foreach (DataRow row in dt.Rows)
                                {
                                    tmpVal = "";
                                    foreach (DataColumn col in dt.Columns)
                                    {
                                        if (col.ColumnName.Contains("$$hashKey"))
                                            continue;   // 20211202 13871,排除$$hasekey
                                                        // 20211228 13871,值進行CInput處理
                                        tmpVal += CombineXMLValue(col.ColumnName.ToLower(), CInput(row[col.ColumnName].ToString()));
                                    }
                                    tmpXml += CombineXMLValueTag(tmpVal);
                                }
                                string argvalue_name = key.ToString();
                                string argname = key.ToString();
                                string argtype = "String";
                                string argdesc = "";
                                result += CombineXMLParameterMultiValue(argvalue_name, argname, argtype, tmpXml, argdesc);
                            }
                            catch (Exception ex)
                            {
                                Log.WriteLog(key + ":Parameter2XML fail", iMESLog.iMESLogLevel.Warn, ex);
                                // 20210513 13871,轉型錯誤直接回傳前端
                                throw;
                            }
                        }
                        else if (string.IsNullOrEmpty(dic[key].ToString()))
                        {
                            string argname1 = key.ToString();
                            string argtype1 = dic[key].GetType().Name;
                            string argdesc1 = "";
                            result += CombineXMLParameter_Space(argname1, argtype1, argdesc1);
                        }
                        else
                        {
                            // 20211228 13871,值進行CInput處理
                            result += CombineXMLParameter(key.ToString(), dic[key].GetType().Name, CInput(dic[key].ToString()), "");
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.WriteLog(key + ":" + ex.ToString(), iMESLog.iMESLogLevel.Warn, ex);
                        // 20210513 13871,轉型錯誤直接回傳前端
                        throw;
                    }
                }
                if (!(t_single == null))
                {
                    foreach (string key in t_single.Keys)
                    {
                        if (t_single[key].GetType().Equals(typeof(DataTable)))
                        {
                            try
                            {
                                DataTable dt = t_single[key] as DataTable;
                                string tmpXml = "";
                                string tmpVal = "";
                                foreach (DataRow row in dt.Rows)
                                {
                                    tmpVal = "";
                                    foreach (DataColumn col in dt.Columns)
                                    {
                                        string argTagName1 = col.ColumnName.ToLower();
                                        string argValue1 = row[col.ColumnName].ToString();
                                        tmpVal += CombineXMLValue(argTagName1, argValue1);
                                    }
                                    tmpXml += CombineXMLValueTag(tmpVal);
                                }
                                string argvalue_name1 = key.ToString();
                                string argname3 = key.ToString();
                                string argtype3 = "String";
                                string argdesc3 = "";
                                result += CombineXMLParameterMultiValue(argvalue_name1, argname3, argtype3, tmpXml, argdesc3);
                            }
                            catch (Exception ex)
                            {
                                Log.WriteLog("Parameter2XML fail", iMESLog.iMESLogLevel.Warn, ex);
                            }
                        }
                        else if (string.IsNullOrEmpty(t_single[key].ToString()))
                        {
                            string argname4 = key.ToString();
                            string argtype4 = t_single[key].GetType().Name;
                            string argdesc4 = "";
                            result += CombineXMLParameter_Space(argname4, argtype4, argdesc4);
                        }
                        else
                        {
                            string argname5 = key.ToString();
                            string argtype5 = t_single[key].GetType().Name;
                            string argvalue1 = t_single[key].ToString();
                            string argdesc5 = "";
                            result += CombineXMLParameter(argname5, argtype5, argvalue1, argdesc5);
                        }
                    }
                }
                if (!(t_global == null))
                {
                    foreach (string key in t_global.Keys)
                    {
                        if (t_single != null && t_single.ContainsKey(key))
                            continue;
                        if (t_global[key].GetType().Equals(typeof(DataTable)))
                        {
                            try
                            {
                                DataTable dt = t_global[key] as DataTable;
                                string tmpXml = "";
                                string tmpVal = "";
                                foreach (DataRow row in dt.Rows)
                                {
                                    tmpVal = "";
                                    foreach (DataColumn col in dt.Columns)
                                    {
                                        string argTagName2 = col.ColumnName.ToLower();
                                        string argValue2 = row[col.ColumnName].ToString();
                                        tmpVal += CombineXMLValue(argTagName2, argValue2);
                                    }
                                    tmpXml += CombineXMLValueTag(tmpVal);
                                }
                                string argvalue_name2 = key.ToString();
                                string argname6 = key.ToString();
                                string argtype6 = "String";
                                string argdesc6 = "";
                                result += CombineXMLParameterMultiValue(argvalue_name2, argname6, argtype6, tmpXml, argdesc6);
                            }
                            catch (Exception ex)
                            {
                                Log.WriteLog("Parameter2XML fail", iMESLog.iMESLogLevel.Warn, ex);
                            }
                        }
                        else if (string.IsNullOrEmpty(t_global[key].ToString()))
                        {
                            string argname7 = key.ToString();
                            string argtype7 = t_global[key].GetType().Name;
                            string argdesc7 = "";
                            result += CombineXMLParameter_Space(argname7, argtype7, argdesc7);
                        }
                        else
                        {
                            string argname8 = key.ToString();
                            string argtype8 = t_global[key].GetType().Name;
                            string argvalue2 = t_global[key].ToString();
                            string argdesc8 = "";
                            result += CombineXMLParameter(argname8, argtype8, argvalue2, argdesc8);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }
            return result;
        }

        #region Combine Response

        /// <summary>
        /// 2020/04/22 雋辰,取得RsponseMessage的json string
        /// </summary>
        /// <param name="response"></param>
        /// <param name="ex">例外狀況</param>
        /// <param name="language">語系</param>
        /// <returns></returns>
        public static string CombineRsponseMessage(iMESCIO.CDO.Common.RsponseMessage response = null, Exception ex = null, string language = "", string stack = "", string resourceDir = "Resource")
        {

            if (response == null)
                response = new iMESCIO.CDO.Common.RsponseMessage();

            try
            {

                if (!(ex == null))
                {
                    response.Code = Get_Exception_Code(ex);
                    response.CodeInformation = Convert.ToString(Translate_iMESCode(response.Code, language));
                    response.Exception = Convert.ToString(Get_Exception_Type(ex));
                    response.Message = TranslateMsg(Convert.ToString(Get_Exception_Message(ex)), language, resourceDir);
                    if (string.IsNullOrEmpty(stack))
                    {
                        response.StackTrace = Convert.ToString(Get_Exception_StackTrace(ex));
                    }
                    else
                    {
                        response.StackTrace = stack;
                    }

                }
            }
            catch (Exception e)
            {
                Exception tmpEx = (Exception)Activator.CreateInstance(e.GetType(), new object[] { e.Message, ex });

                response.Code = "0000-200091";
                response.CodeInformation = Convert.ToString(Translate_iMESCode(response.Code, language));
                response.Exception = Convert.ToString(Get_Exception_Type(tmpEx));
                string argstrInput = Convert.ToString(Get_Exception_Type(tmpEx));
                response.Message = CInput(argstrInput);
                string argstrInput1 = Convert.ToString(Get_Exception_StackTrace(tmpEx));
                response.StackTrace = CInput(argstrInput1);
            }

            return response.SerializeObjectData();

        }

        /// <summary>
        /// 2020/04/22 雋辰,取得"ex"內含所有Exception的訊息
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public static object Get_Exception_Message(Exception ex)
        {

            string result = "";
            var tmpEx = new Exception(ex.Message, ex);

            while (!(tmpEx.InnerException == null))
            {
                result += tmpEx.InnerException.Message + ";";
                tmpEx = tmpEx.InnerException;
            }

            return result;

        }

        /// <summary>
        /// 2020/04/22 雋辰,取得"ex"內含所有Exception的例外堆疊資訊
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public static object Get_Exception_StackTrace(Exception ex)
        {

            string result = "";
            var tmpList = new List<string>();
            string divider = "----- 內部例外狀況堆疊追蹤的結尾 ---";
            var tmpEx = new Exception(ex.Message, ex);

            while (!(tmpEx.InnerException == null))
            {
                tmpList.Add(tmpEx.InnerException.StackTrace);
                tmpList.Add(divider);

                tmpEx = tmpEx.InnerException;
            }
            if (tmpList[tmpList.Count - 1] == divider)
                tmpList.RemoveAt(tmpList.Count - 1);

            for (int i = 0, loopTo = tmpList.Count - 1; i <= loopTo; i++)
            {
                result += tmpList[i];
                if (i < tmpList.Count - 1)
                    result += Constants.vbCrLf;
            }

            return result;

        }

        /// <summary>
        /// 2020/04/22 雋辰,取得"ex"內含所有Exception的類別
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public static object Get_Exception_Type(Exception ex)
        {

            string result = "";
            var tmpList = new List<string>();
            string divider = "--- 內部例外 ---";
            var tmpEx = new Exception(ex.Message, ex);

            while (!(tmpEx.InnerException == null))
            {
                tmpList.Add(tmpEx.InnerException.GetType().ToString());
                tmpList.Add(divider);

                tmpEx = tmpEx.InnerException;
            }
            if (tmpList[tmpList.Count - 1] == divider)
                tmpList.RemoveAt(tmpList.Count - 1);

            for (int i = 0, loopTo = tmpList.Count - 1; i <= loopTo; i++)
            {
                result += tmpList[i];
                if (i < tmpList.Count - 1)
                    result += Constants.vbCrLf;
            }

            return result;

        }

        /// <summary>
        /// 2020/05/22 雋辰,取出iMES Code
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        public static string Get_Exception_Code(Exception ex)
        {
            string code = "0000-200091";
            var tmpEx = new Exception(ex.Message, ex);

            while (!(tmpEx.InnerException == null))
            {
                if (tmpEx.InnerException is iMESException.MESException)
                {
                    code = Convert.ToString((tmpEx.InnerException as iMESException.MESException).ErrorCode);
                    break;
                }
                tmpEx = tmpEx.InnerException;
            }

            return code;

        }

        #endregion

    }


    internal class iMES_ResponseMessage
    {
        public string code { get; set; }
        public string exception { get; set; }
        public string message { get; set; }
        public string stacktrace { get; set; }

        public string CombineRsponseMessage(iMES_ResponseMessage oResponseMsg, string LanguageMode, string resourceDir = "Resource")
        {

            try
            {
                if (oResponseMsg.code != "0")
                {
                    string argstrInput = TranslateMsg(oResponseMsg.exception, LanguageMode, resourceDir);
                    oResponseMsg.exception = CInput(argstrInput);
                }
            }
            catch (Exception ex)
            {
                oResponseMsg.code = "0000-999999";
                oResponseMsg.exception = ex.Message;
                oResponseMsg.message = ex.Message;
                oResponseMsg.stacktrace = ex.StackTrace;
            }

            return JsonConvert.SerializeObject(oResponseMsg);

        }
    }
}