using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DirectoryDownload
{
    class InvokeMethod
    {
        public string Post(string Url, string jsonParas)
        {
            GlobalVariables.writeLog("URL:" + Url);
            GlobalVariables.writeLog("jsonParas:" + jsonParas);
            string strURL = Url;
            //创建一个HTTP请求  
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strURL);
            //Post请求方式  
            request.Method = "POST";
            //内容类型
            request.ContentType = "application/json";


            //设置参数，并进行URL编码 

            string paraUrlCoded = jsonParas;//System.Web.HttpUtility.UrlEncode(jsonParas);   

            byte[] payload;
            //将Json字符串转化为字节  
            payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
            //设置请求的ContentLength   
            request.ContentLength = payload.Length;
            //发送请求，获得请求流 

            Stream writer;
            try
            {
                writer = request.GetRequestStream();//获取用于写入请求数据的Stream对象
            }
            catch (Exception)
            {
                writer = null;
                GlobalVariables.writeLog("连接服务器失败!");
            }
            //将请求参数写入流
            writer.Write(payload, 0, payload.Length);
            writer.Close();//关闭请求流
                           // String strValue = "";//strValue为http响应所返回的字符流
            HttpWebResponse response;
            try
            {
                //获得响应流
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                response = ex.Response as HttpWebResponse;
            }
            Stream s = response.GetResponseStream();
            //  Stream postData = Request.InputStream;
            StreamReader sRead = new StreamReader(s);
            string postContent = sRead.ReadToEnd();
            sRead.Close();
            //解析postContent,插入医保交易日志表
            IrisServices iris = new IrisServices();
            dynamic joIris = new JObject();
            JObject joTmp = new JObject();
            joTmp.Add("In", jsonParas);
            joTmp.Add("out",postContent);
            joIris.code = "09010021";
            joIris.Add("params", JObject.FromObject(joTmp));
            iris.Invoke(joIris.ToString());
            return postContent;//返回Json数据
        }
        public bool Download(string url, string strParams)
        {
            try
            {
                GlobalVariables.writeLog("strParams" + strParams);
                JObject jsonInParam = JObject.Parse(strParams);
                string fileName = (string)jsonInParam["input"]["fsDownloadIn"]["filename"];
                GlobalVariables.writeLog("filename" + fileName);
                string filePath = System.Environment.CurrentDirectory + "\\" + fileName;
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }
                FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                string strURL = url;
                //创建一个HTTP请求  
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strURL);
                //Post请求方式  
                request.Method = "POST";
                //内容类型
                request.ContentType = "application/json";


                //设置参数，并进行URL编码 

                string paraUrlCoded = strParams;//System.Web.HttpUtility.UrlEncode(jsonParas);   

                byte[] payload;
                //将Json字符串转化为字节  
                payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
                //设置请求的ContentLength   
                request.ContentLength = payload.Length;
                Stream writer;
                try
                {
                    writer = request.GetRequestStream();//获取用于写入请求数据的Stream对象
                }
                catch (Exception)
                {
                    writer = null;
                    Console.Write("连接服务器失败!");
                }
                //将请求参数写入流
                writer.Write(payload, 0, payload.Length);
                writer.Close();//关闭请求流
                               // String strValue = "";//strValue为http响应所返回的字符流


                //发送请求并获取相应回应数据
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                Stream responseStream = response.GetResponseStream();

                //创建本地文件写入流
                byte[] bArr = new byte[1024];
                int iTotalSize = 0;
                int size = responseStream.Read(bArr, 0, (int)bArr.Length);
                while (size > 0)
                {
                    iTotalSize += size;
                    fs.Write(bArr, 0, size);
                    size = responseStream.Read(bArr, 0, (int)bArr.Length);
                }
                fs.Close();
                responseStream.Close();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }


        }
    }
    class IrisServices
    {
        public string Invoke(string data)
        {
            GlobalVariables.writeLog("入参：" + data);
            //先根据用户请求的uri构造请求地址
            string url = string.Format("{0}/{1}", GlobalVariables.irisServiceIP, GlobalVariables.irisServiceURL);
            //log.Write(serviceUrl);
            //log.Write(data);
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
            //创建Web访问对象
            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
            //
            //把用户传过来的数据转成“UTF-8”的字节流
            byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(data);

            myRequest.Method = "POST";
            myRequest.ContentLength = buf.Length;
            myRequest.ContentType = "application/json";
            //myRequest.Headers.Add("Authorization", hisauthorization);
            //myRequest.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
            //myRequest.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36");
            myRequest.Headers.Add("Authorization", GlobalVariables.irisServiceAuthorization);
            myRequest.MaximumAutomaticRedirections = 1;
            myRequest.AllowAutoRedirect = true;
            //发送请求
            Stream stream = myRequest.GetRequestStream();
            stream.Write(buf, 0, buf.Length);
            stream.Close();
            //获取接口返回值
            //通过Web访问对象获取响应内容
            HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
            //通过响应内容流创建StreamReader对象，因为StreamReader更高级更快
            StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
            //string rtn = HttpUtility.UrlDecode(reader.ReadToEnd());//如果有编码问题就用这个方法
            string rtn = reader.ReadToEnd();//利用StreamReader就可以从响应内容从头读到尾
            reader.Close();
            myResponse.Close();
            GlobalVariables.writeLog("出参:" + rtn);
            return rtn;
        }
    }
    class YinHaiCom
    {
        string progID1 = "YinHai.CHS.InterfaceSCS";
        System.Type YinHaiComType;
        object  YinHaiComInstance;

        //public YinHaiCom()
        //{
        //    // 与指定 ProgID 关联的类型，即获取相应的Com对象
        //    if (YinHaiComType == null)
        //    {
        //        GlobalVariables.writeLog("开始创建银海Com对象");
        //        YinHaiComType = System.Type.GetTypeFromProgID(progID);
        //        Init();
                
        //    }
        //    else
        //    {
        //        GlobalVariables.writeLog("银海Com对象已存在");
        //    }
        //}

        public int Init()
        {
            YinHaiComType = System.Type.GetTypeFromProgID(progID1);
            // 创建Com的实例
            if (YinHaiComType != null)
            {
                GlobalVariables.writeLog("开始COM组件Init");
                //创建实例
                YinHaiComInstance = Activator.CreateInstance(YinHaiComType);
                if (YinHaiComInstance != null)
                {
                    GlobalVariables.writeLog("Init实例创建成功");
                }
                //设置需要设置的参数值
                object[] ParamArray = new object[2];
                ParamArray[0] = 0;
                ParamArray[1] = "";
                ParameterModifier[] ParamMods = new ParameterModifier[1];
                ParamMods[0] = new ParameterModifier(2); // 初始化为接口参数的个数
                ParamMods[0][0] = true;
                ParamMods[0][1] = true; // 设置第二个参数为返回参数，调用含有ParameterModifier数组的重载函数

                YinHaiComType.InvokeMember("yh_CHS_init", // 接口函数名
                 BindingFlags.Default | BindingFlags.InvokeMethod,
                null,
                YinHaiComInstance, // 调用的COM组件
                ParamArray, // 参数数组
                ParamMods, // 指定返回参数的ParameterModifier数组
                null,
                null);

                string Msg = "加载成功：" + ParamArray[1].ToString();
                GlobalVariables.writeLog(Msg + "___" + ParamArray[0].ToString());
                return (int)ParamArray[0];
            }
            else
            {
                string Msg = "YinHaiComType加载失败！";
                GlobalVariables.writeLog(Msg);
                return 1;
            }
        }
        public void Call(string infno,string input,out string output)
        {

            if (YinHaiComType != null)
            {
                //创建实例,不能再次创建，否则会提示没有初始化
                //YinHaiComInstance = Activator.CreateInstance(YinHaiComType);
                if (YinHaiComInstance != null)
                {
                    GlobalVariables.writeLog("实例创建成功,准备调用Call服务");
                }
                else
                {
                    output = "实例不存在！";
                    GlobalVariables.writeLog("实例不存在");
                    return;
                }
                GlobalVariables.writeLog("入参infno:" + infno);
                GlobalVariables.writeLog("入参input:" + input);
                //设置需要设置的参数值
                object[] ParamArray = new object[3];
                ParamArray[0] = infno;
                ParamArray[1] = input;
                ParamArray[2] = "";
                ParameterModifier[] ParamMods = new ParameterModifier[1];
                ParamMods[0] = new ParameterModifier(3); // 初始化为接口参数的个数
                //ParamMods[0][0] = false;
                //ParamMods[0][1] = false; 
                ParamMods[0][2] = true;
                YinHaiComType.InvokeMember("yh_CHS_call", // 接口函数名
                 BindingFlags.Default | BindingFlags.InvokeMethod,
                null,
                YinHaiComInstance, // 调用的COM组件
                ParamArray, // 参数数组
                ParamMods, // 指定返回参数的ParameterModifier数组
                null,
                null);

                output = ParamArray[2].ToString();
            }
            else
            {
                output = "COM加载失败！";
                GlobalVariables.writeLog("COM加载失败！");

            }

            //  if (YinHaiComType == null)
            //  {
            //      output = "未找到组件，请先调用ComInit或者检查运行环境！";
            //      GlobalVariables.writeLog(output);
            //      return ;

            //  }
            //  //设置需要设置的参数值
            //  object[] ParamArray = new object[3];
            //  ParamArray[0] = infno;
            //  ParamArray[1] = input;
            //  ParamArray[2] = "";
            //  ParameterModifier[] ParamMods = new ParameterModifier[1];
            //  ParamMods[0] = new ParameterModifier(3); // 初始化为接口参数的个数
            //  ParamMods[0][2] = true; // 设置第二个参数为返回参数
            //                          //调用含有ParameterModifier数组的重载函数
            //  YinHaiComType.InvokeMember("yh_CHS_call", // 接口函数名
            //   BindingFlags.Default | BindingFlags.InvokeMethod,
            //  null,
            //  YinHaiComInstance, // 调用的COM组件
            //  ParamArray, // 参数数组
            //  ParamMods, // 指定返回参数的ParameterModifier数组
            //  null,
            //null);
            //  output = ParamArray[2].ToString();
        }

        public void Destroy(out string output)
        {
            // 创建Com的实例
            if (YinHaiComType != null)
            {
                //创建实例
                YinHaiComInstance = Activator.CreateInstance(YinHaiComType);
                if (YinHaiComInstance != null)
                {
                    GlobalVariables.writeLog("实例创建成功,准备调用Call服务");
                }
                else
                {
                    output = "实例不存在！";
                    GlobalVariables.writeLog("实例不存在");
                    return;
                }
                //设置需要设置的参数值
                object[] ParamArray = new object[0];
                ParameterModifier[] ParamMods = new ParameterModifier[0];
                ParamMods[0] = new ParameterModifier(0); // 初始化为接口参数的个数
                YinHaiComType.InvokeMember("yh_CHS_destroy", // 接口函数名
                 BindingFlags.Default | BindingFlags.InvokeMethod,
                null,
                YinHaiComInstance, // 调用的COM组件
                ParamArray, // 参数数组
                ParamMods, // 指定返回参数的ParameterModifier数组
                null,
                null);

                output = "destroy成功！";
            }
            else
            {
                output = "COM加载失败！";
                GlobalVariables.writeLog("COM加载失败！");

            }
        }


    }

    #region

    class DllInvoke
    {
        public static object ManagedInvoke(string DllFileName, string NameSpace, string ClassName, string MethodName, object[] ObjArrayParams)
        {
            //GlobalVariables.writeLog("程序集信息：" + NameSpace + "." + ClassName + "." + MethodName);
            //GlobalVariables.writeLog("文件全路径：" + DllFileName);
            //GlobalVariables.writeLog("命名空间.类.方法：" + NameSpace + "." + ClassName + "."  + MethodName);
            //GlobalVariables.writeLog("入参：" + ObjArrayParams[0].ToString());
            object o = new object();
            string inMes = "";
            try
            {
                //载入程序集 
                Assembly DllAssembly = Assembly.LoadFile(DllFileName);
                //MessageBox.Show(NameSpace + ":" + ClassName);
                Type DllType = DllAssembly.GetType(NameSpace + "." + ClassName);

                if (DllType == null)
                {
                    o = NameSpace + "." + ClassName + "未获取到DllType";
                    return o;
                }

                //查找要调用的方 法并进行调用 
                MethodInfo MyMethod = DllType.GetMethod(MethodName);

                if (MyMethod != null)
                {
                    object mObject = Activator.CreateInstance(DllType);
                    try
                    {
                        if (ObjArrayParams == null)
                        {

                            o = MyMethod.Invoke(mObject, null);
                                 
                        }
                        else
                        {
                            o = MyMethod.Invoke(mObject, new object[] { ObjArrayParams[0].ToString() });
                           }

                    }
                    catch (Exception ex)
                    {
                        o =ex.ToString();
                        if (ex.InnerException != null)
                        {
                            inMes = ex.InnerException.Message;
                            o = inMes;
                        }

                    }

                }


            }
            catch (Exception ex)
            {
                o = ex.ToString();
                if (ex.InnerException != null)
                {
                    inMes = ex.InnerException.Message;
                    o = inMes.ToString();
                }

            }
            //GlobalVariables.writeLog("出参：" + o.ToString());
            return o;
        }
    }
    #endregion
}
