using System;
using System.Reflection;
using Apache.NMS;
using Microsoft.VisualBasic;

namespace tcEAI_C
{

    /// <summary>
/// 20211027 13871,共用功能
/// </summary>
    public class clsCom
    {

        /// <summary>
    /// 20211027 13871,Reflection方法
    /// </summary>
    /// <param name="strComponent">DLL Name</param>
    /// <param name="strClassName">Class Name</param>
    /// <param name="strMethodName">Function Name</param>
    /// <param name="mi"></param>
    /// <param name="obj"></param>
    /// <returns></returns>
        public static bool DetermineCustomized_Constructor(string strComponent, string strClassName, string strMethodName, ref MethodInfo mi, ref object obj)
        {
            bool DetermineCustomized_ConstructorRet = default(bool);
            bool blnResult = false;

            DetermineCustomized_ConstructorRet = false;
            try
            {
                blnResult = DetermineMethod_Constructor(strComponent, strClassName, strMethodName, ref mi, ref obj);
            }
            catch (Exception ex)
            {
            }

            finally
            {
                DetermineCustomized_ConstructorRet = blnResult;
            }

            return DetermineCustomized_ConstructorRet;

        }

        /// <summary>
    /// 20211027 13871,Reflection找出Method
    /// </summary>
        public static bool DetermineMethod_Constructor(string strComponent, string strClassName, string strMethodName, ref MethodInfo mi, ref object obj)
        {
            string strAppBase = AppDomain.CurrentDomain.BaseDirectory;
            string strFilePath = "";
            Assembly mainAssembly;
            Type t;
            Type[] argumentTypes;
            ConstructorInfo ctor;

            MethodInfo[] aryMethos;

            try
            {
                strFilePath = strAppBase.TrimEnd('\\') + @"\bin\" + strComponent;
                mainAssembly = Assembly.LoadFrom(strFilePath);
                t = mainAssembly.GetType(mainAssembly.GetName().Name + "." + strClassName, true, true);
                // 20211211 13871,支援Module
                if (t.GetConstructors().Length > 0)
                {
                    argumentTypes = Type.EmptyTypes;
                    ctor = t.GetConstructor(argumentTypes);
                    obj = ctor.Invoke(new object[] { });
                }
                strMethodName = Strings.Replace(strMethodName, ".", "_");
                aryMethos = t.GetMethods();
                foreach (MethodInfo item in aryMethos)
                {
                    if ((strMethodName.ToUpper() ?? "") == (item.Name.ToUpper() ?? ""))
                    {
                        mi = item;
                        return true;
                    }
                }

                if (mi == null)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
    /// 20211027 13871,取得Method的參數預設值陣列
    /// </summary>
    /// <param name="strComponent">DLL Name,可不傳副檔名,會自動補.dll</param>
    /// <param name="strClassName">Class Name</param>
    /// <param name="strMethodName">Method Name</param>
    /// <returns></returns>
        public static object[] funGetMethodParameters(string strComponent, string strClassName, string strMethodName)
        {
            object[] funGetMethodParametersRet = default(object[]);
            try
            {
                var mi = default(MethodInfo);
                var obj = default(object);
                if (!strComponent.ToUpper().Contains(".DLL"))
                {
                    strComponent = strComponent + ".dll";
                }

                if (!DetermineCustomized_Constructor(strComponent, strClassName, strMethodName, ref mi, ref obj))
                {
                    throw new iMESException.MESException("0000-200003", strComponent + "." + strClassName + "," + strMethodName + " [%METHOD%] [%NOT FOUND%]");
                }

                int iParameterLength = mi.GetParameters().Length;
                var aryParameter = new object[iParameterLength];
                for (int i = 0, loopTo = mi.GetParameters().Length - 1; i <= loopTo; i++)
                {
                    try
                    {
                        aryParameter[i] = mi.GetParameters()[i].DefaultValue;
                    }
                    catch (Exception)
                    {
                        if (mi.GetParameters()[i].ParameterType == typeof(DateTime))
                            aryParameter[i] = default(DateTime);
                        else
                            throw;
                    }
                }
                funGetMethodParametersRet = aryParameter;
            }
            catch (Exception ex)
            {
                throw;
            }

            return funGetMethodParametersRet;
        }

        /// <summary>
    /// 20211027 13871,執行指定DLL、Class、Method,無法執行多載Method
    /// </summary>
    /// <param name="strComponent">DLL Name,可不傳副檔名,會自動補.dll</param>
    /// <param name="strClassName">Class Name</param>
    /// <param name="strMethodName">Method Name</param>
    /// <param name="aryParameters"></param>
        public static object funExecuteMethod(string strComponent, string strClassName, string strMethodName, ref object[] aryParameters)
        {
            object funExecuteMethodRet = default(object);
            try
            {
                var mi = default(MethodInfo);
                var obj = default(object);
                if (!strComponent.ToUpper().Contains(".DLL"))
                {
                    strComponent = strComponent + ".dll";
                }

                if (!DetermineCustomized_Constructor(strComponent, strClassName, strMethodName, ref mi, ref obj))
                {
                    throw new iMESException.MESException("0000-200003", strComponent + "." + strClassName + "," + strMethodName + " [%METHOD%] [%NOT FOUND%]");
                }

                funExecuteMethodRet = mi.Invoke(obj, aryParameters);
            }

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

            return funExecuteMethodRet;
        }

        // 20211208 13871,從clsEAP移植
        public static Exception funGetRealException(Exception ex)
        {
            Exception funGetRealExceptionRet = default(Exception);
            try
            {
                funGetRealExceptionRet = ex;

                if (ex is TargetInvocationException && ex.InnerException != null)
                {
                    funGetRealExceptionRet = funGetRealException(ex.InnerException);
                }
            }
            catch (Exception ex2)
            {
                throw;
            }

            return funGetRealExceptionRet;
        }



        #region --- Combine Input Xml ---


        public static string CombineXMLIdentity(ref string TransactionID, ref string ModuleID, ref string FunctionID, ref string ComputerName, ref string CurUserNo, ref string SendTime)
        {
            string CombineXMLIdentityRet = default(string);
            CombineXMLIdentityRet = "<transactionid>" + TransactionID + "</transactionid>" + "<moduleid>" + ModuleID + "</moduleid>" + "<functionid>" + FunctionID + "</functionid>" + "<computername>" + ComputerName + "</computername>" + "<curuserno>" + CurUserNo + "</curuserno>" + "<sendtime>" + SendTime + "</sendtime>";
            return CombineXMLIdentityRet;
        }

        public static string CombineXMLParameter(ref string value_name, ref string name, ref string type, ref string value, ref string desc)
        {
            string CombineXMLParameterRet = default(string);

            CombineXMLParameterRet = "<" + value_name.ToLower() + ">" + "<name>" + name + "</name>" + "<type>" + type + "</type>" + "<value>" + value + "</value>" + "<desc>" + desc + "</desc>" + "</" + value_name.ToLower() + ">";
            return CombineXMLParameterRet;

        }

        public static string CombineXMLParameter(ref string name, ref string type, ref string value, ref string desc)
        {
            string CombineXMLParameterRet = default(string);
            CombineXMLParameterRet = "<" + name.ToLower() + ">" + "<name>" + name + "</name>" + "<type>" + type + "</type>" + "<value>" + value + "</value>" + "<desc>" + desc + "</desc>" + "</" + name.ToLower() + ">";
            return CombineXMLParameterRet;
        }

        public static string CombineXMLValue(ref string TagName, ref string Value)
        {
            string CombineXMLValueRet = default(string);
            CombineXMLValueRet = "<" + TagName + ">" + Value + "</" + TagName + ">";
            return CombineXMLValueRet;
        }

        public static string CombineXMLValueTag(ref string Value)
        {
            string CombineXMLValueTagRet = default(string);
            CombineXMLValueTagRet = "<value>" + Value + "</value>";
            return CombineXMLValueTagRet;
        }

        public static string CombineXMLRequest(ref string strIdentity, ref string strParameter)
        {
            string CombineXMLRequestRet = default(string);

            CombineXMLRequestRet = "<request>" + "<identity>" + strIdentity + "</identity>";
            if (!string.IsNullOrEmpty(strParameter))
            {
                CombineXMLRequestRet = CombineXMLRequestRet + "<parameter>" + strParameter + "</parameter>";
            }
            CombineXMLRequestRet = CombineXMLRequestRet + "</request>";
            return CombineXMLRequestRet;

        }

        public static string CombineXMLParameterMultiValue(ref string value_name, ref string name, ref string type, ref string value, ref string desc)
        {
            string CombineXMLParameterMultiValueRet = default(string);
            // Value不用加上Tag
            CombineXMLParameterMultiValueRet = "<" + value_name.ToLower() + ">" + "<name>" + name + "</name>" + "<type>" + type + "</type>" + value + "<desc>" + desc + "</desc>" + "</" + value_name.ToLower() + ">";
            return CombineXMLParameterMultiValueRet;
        }

        public static string CombineXMLAdditional(ref string strAdditional)
        {
            string CombineXMLAdditionalRet = default(string);
            CombineXMLAdditionalRet = "<additional>" + strAdditional;
            CombineXMLAdditionalRet = CombineXMLAdditionalRet + "</additional>";
            return CombineXMLAdditionalRet;
        }

        public static string CombineAddXML_Add(ref string name, ref string type, ref string value)
        {
            string CombineAddXML_AddRet = default(string);
            CombineAddXML_AddRet = "<field>" + "<name>" + name + "</name>" + "<type>" + type + "</type>" + "<value>" + value + "</value>" + "</field>";
            return CombineAddXML_AddRet;
        }

        public static string CombineAddXML_Edit(ref string name, ref string type, ref string value)
        {
            string CombineAddXML_EditRet = default(string);
            CombineAddXML_EditRet = "<field>" + "<name>" + name + "</name>" + "<type>" + type + "</type>" + "<value>" + value + "</value>" + "</field>";
            return CombineAddXML_EditRet;
        }

        public static string CombineAddXML_Field(ref string name)
        {
            string CombineAddXML_FieldRet = default(string);
            CombineAddXML_FieldRet = "<field>" + "<name>" + name + "</name>" + "</field>";
            return CombineAddXML_FieldRet;
        }

        public static string CombineAddXML_Condition(string condition)
        {
            string CombineAddXML_ConditionRet = default(string);

            // 2007/03/22,sammi.呼叫CombineAddXML_Condition時,不可加CInput.
            // 因CInput會將單引號轉成二個單引號,若Condition為下述範例時,會Error.
            // strAdditional = CombineXMLAdditional(CombineAddXML_Condition("ModuleType in ('REWORK','SLR')"))
            // strParameter += strAdditional

            CombineAddXML_ConditionRet = "<condition>" + condition + "</condition>";
            return CombineAddXML_ConditionRet;

        }

        public static string CInput(string strInput)
        {
            string CInputRet = default(string);
            // 將傳入值內的單引號轉換為可存入資料庫的格式
            // 將傳入值內的 &, >, < 三個特殊字元轉換為XmlDocument可解譯之代替符號                  
            // 傳入值: strInput包含特殊字元的字串
            // 傳回值: 將特殊字元變更為代替符號的字串

            // 轉換 ' 為 '' (單引號轉為兩個單引號)
            CInputRet = Strings.Replace(strInput, "'", "''");

            // 轉換 & 為 &amp;
            CInputRet = Strings.Replace(CInputRet, "&", "&amp;");

            // CInput = Replace(CInput, """", "''")   'AddFlow的Xml字串不可將雙引號轉為兩個單引號,XMLToFlow會Error

            // 轉換 > 為 &gt;
            CInputRet = Strings.Replace(CInputRet, ">", "&gt;");

            // 轉換 < 為 &lt;
            CInputRet = Strings.Replace(CInputRet, "<", "&lt;");
            return CInputRet;

        }

        #endregion
    }
}