using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Net;
using System.IO;

using Newtonsoft.Json;

using Cosmos.BaseFrame;
using Cosmos.UserFrame;
using Cosmos.ServiceProvider;
using Cosmos.Common;


using System.Net.Security;
using System.Security.Cryptography.X509Certificates;


namespace Cosmos.Network
{
    public class NetworkHttp : INetworkHttp
    {
        private SManager sManager = new SManager();                                 // 이 객체를 통해 업무 Service 호출
        private StateServer StateObject = (StateServer)StateServer.GetInstance();   // StateObject : StateServer Object (객체)
        private PosStatus m_cPosStatus;                                             // 기본정보 참조
        private DeviceStatus m_cDevStatus;                                          // 장비정보 참조 

        public NetworkHttp()
        {
            m_cPosStatus = (PosStatus)StateObject.POS;                              // POS 기본정보
            m_cDevStatus = (DeviceStatus)StateObject.DEVICE;                        // POS 장치정보
        }

        /// <summary>
        /// 해피오더 POST방식 Request
        /// </summary>
        /// <param name="sUrl"></param>
        /// <param name="sWorkType"></param>
        /// <param name="htReqData"></param>
        /// <param name="sRespJsonData"></param>
        /// <returns></returns>
        public int HttpJsonPOST_SendReceive(string sUrl, string sWorkType, Hashtable htReqData, ref Hashtable htRspData, ref string sRespJsonData)
        {
            int iRet = BaseCom.NG;
            string sRespString = string.Empty;

            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sUrl + sWorkType);

                string sSendJsonData = JsonConvert.SerializeObject(htReqData);

                UserLog.WriteLogFile(UserCom.LOG_SOCK,
                                     UserCom.INFO_LEVEL,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                     sSendJsonData);

                byte[] reqByte = Encoding.UTF8.GetBytes(sSendJsonData);

                req.Method = "POST";
                req.ContentType = "application/json";
                req.ContentLength = reqByte.Length;

                // create our stream to send
                Stream webDataStream = req.GetRequestStream();
                webDataStream.Write(reqByte, 0, reqByte.Length);

                // get thre response from our stream
                WebResponse resp = req.GetResponse();
                webDataStream = resp.GetResponseStream();

                // convert the result into a string
                StreamReader respStreamReader = new StreamReader(webDataStream);
                string respFromServer = respStreamReader.ReadToEnd();

                respStreamReader.Close();

                UserLog.WriteLogFile(UserCom.LOG_SOCK,
                                     UserCom.INFO_LEVEL,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                     respFromServer);

                Hashtable temp = JsonConvert.DeserializeObject<Hashtable>(respFromServer);

                foreach (string key in temp.Keys)
                {
                    string jsonString = temp[key].ToString();
                    if (key.Equals("status"))
                    {
                        Hashtable htHeader = JsonConvert.DeserializeObject<Hashtable>(jsonString);
                        if (htHeader["status"].ToString().Equals("200"))
                        {
                            iRet = BaseCom.OK;
                        }
                        htRspData = htHeader;
                    }
                    else
                    {
                        sRespJsonData = jsonString;
                    }
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                                     ex.ToString());
            }

            return iRet;
        }
        /// <summary>
        /// 해피오더 GET방식 Request
        /// </summary>
        /// <param name="sUrl">서버URL</param>
        /// <param name="sWorkType">작업구분</param>
        /// <param name="sReqData">요청Data</param>
        /// <param name="sRespJsonData">JSON String 형태의 응답 데이터</param>
        /// <returns></returns>
        public int HttpJsonGET_SendReceive(string sUrl, string sWorkType, string sReqData, ref string sRespJsonData)
        {
            int iRet = BaseCom.NG;
            string sRespString = string.Empty;

            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sUrl + sWorkType + "?" + sReqData);
                req.Method = "GET";

                UserLog.WriteLogFile(UserCom.LOG_SOCK,
                                     UserCom.INFO_LEVEL,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                     sUrl + sWorkType + "?" + sReqData);

                using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
                {
                    Stream stream = resp.GetResponseStream();
                    //StreamReader streamReader = new StreamReader(stream, Encoding.GetEncoding("UTF-8"));
                    StreamReader streamReader = new StreamReader(stream, Encoding.GetEncoding("ks_c_5601-1987"));
                    sRespString = streamReader.ReadToEnd();
                    streamReader.Close();
                }

                UserLog.WriteLogFile(UserCom.LOG_SOCK,
                                     UserCom.INFO_LEVEL,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // Project Name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // Class Name (Class Name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // Function Name (Function Name (함수명))
                                     sRespString);

                Hashtable temp = JsonConvert.DeserializeObject<Hashtable>(sRespString);

                foreach (string key in temp.Keys)
                {
                    string jsonString = temp[key].ToString();
                    if (key.Equals("status"))
                    {
                        Hashtable htHeader = JsonConvert.DeserializeObject<Hashtable>(jsonString);
                        if (htHeader["status"].ToString().Equals("200"))
                        {
                            iRet = BaseCom.OK;
                        }
                    }
                    else
                    {
                        sRespJsonData = jsonString;
                    }
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                                     ex.ToString());
            }

            return iRet;
        }

        /// <summary>
        /// GET방식 Request
        /// </summary>
        /// <param name="sUrl">서버URL</param>
        /// <param name="sWorkType">작업구분</param>
        /// <param name="sReqData">요청Data</param>
        /// <param name="sRespJsonData">JSON String 형태의 응답 데이터</param>
        /// <returns></returns>
        public int HttpGET_SendReceive(string sUrl, string sWorkType, string sReqData, string sEncodingFlag, ref string sRespData)
        {
            int iRet = BaseCom.NG;
            string sRespString = string.Empty;
            StreamReader streamReader = null;

            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sUrl + sWorkType + "?" + sReqData);
                req.Method = "GET";

                using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
                {
                    Stream stream = resp.GetResponseStream();

                    if (sEncodingFlag == PosConst.ENCODING_FLAG.UTF)
                    {
                        streamReader = new StreamReader(stream, Encoding.GetEncoding("UTF-8"));
                    }
                    else
                    {
                        streamReader = new StreamReader(stream, Encoding.GetEncoding("ks_c_5601-1987"));
                    }

                    sRespString = streamReader.ReadToEnd();
                    streamReader.Close();
                }

                iRet = BaseCom.OK;

                sRespData = sRespString;
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                                     ex.ToString());
            }

            return iRet;
        }

        /// <summary>
        /// 해피버즈 http 통신
        /// </summary>
        /// <param name="sUrl"></param>
        /// <param name="sWorkType"></param>
        /// <param name="htReqData"></param>
        /// <param name="htRspData"></param>
        /// <param name="sRespJsonData"></param>
        /// <returns></returns>
        public int HttpJsonPOST_SendReceiveForBuzz(string sUrl, string sWorkType, Hashtable htReqData, ref Hashtable htRspData)
        {
            int iRet = BaseCom.NG;
            string sRespString = string.Empty;

            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sUrl + sWorkType);

                string sSendJsonData = JsonConvert.SerializeObject(htReqData);
                byte[] reqByte = Encoding.UTF8.GetBytes(sSendJsonData);

                req.Method = "POST";
                req.ContentType = "application/json";
                req.ContentLength = reqByte.Length;

                // create our stream to send
                Stream webDataStream = req.GetRequestStream();
                webDataStream.Write(reqByte, 0, reqByte.Length);

                // get thre response from our stream
                WebResponse resp = req.GetResponse();
                webDataStream = resp.GetResponseStream();

                // convert the result into a string
                StreamReader respStreamReader = new StreamReader(webDataStream);
                string respFromServer = respStreamReader.ReadToEnd();

                respStreamReader.Close();

                htRspData = JsonConvert.DeserializeObject<Hashtable>(respFromServer);

                if (htRspData["result"].Equals(true))
                {
                    iRet = BaseCom.OK;
                }
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                                     ex.ToString());
            }

            return iRet;
        }

        /// <summary>
        /// 관공서 방문 알림 통신
        /// </summary>
        /// <param name="sUrl"></param>
        /// <param name="sWorkType"></param>
        /// <param name="htReqData"></param>
        /// <param name="htRspData"></param>
        /// <param name="sRespJsonData"></param>
        /// <returns></returns>
        public int HttpPOST_SendReceiveForGoverVisit(string sUrl, string sWorkType, Hashtable htReqData, ref Hashtable htRspData)
        {
            int iRet = BaseCom.NG;
            string sRespString = string.Empty;

            try
            {
                // 요청 String -> 요청 Byte 변환
                byte[] byteDataParams = UTF8Encoding.UTF8.GetBytes(htReqData.ToString());

                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sUrl + sWorkType);

                req.Method = "POST";    // 기본값 "GET"
                req.ContentType = "application/x-www-form-urlencoded";
                req.ContentLength = byteDataParams.Length;

                // 요청 Byte -> 요청 Stream 변환
                Stream stDataParams = req.GetRequestStream();
                stDataParams.Write(byteDataParams, 0, byteDataParams.Length);
                stDataParams.Close();

                // 요청, 응답 받기
                HttpWebResponse response = (HttpWebResponse)req.GetResponse();


                if (response.StatusCode == HttpStatusCode.OK)
                {
                    iRet = BaseCom.OK;
                }

                //HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sUrl + sWorkType);

                //string sSendJsonData = JsonConvert.SerializeObject(htReqData);
                //byte[] reqByte = Encoding.UTF8.GetBytes(sSendJsonData);

                //req.Method = "POST";
                //req.ContentType = "application/json";
                //req.ContentLength = reqByte.Length;

                //// create our stream to send
                //Stream webDataStream = req.GetRequestStream();
                //webDataStream.Write(reqByte, 0, reqByte.Length);

                //// get thre response from our stream
                //WebResponse resp = req.GetResponse();
                //webDataStream = resp.GetResponseStream();

                //// convert the result into a string
                //StreamReader respStreamReader = new StreamReader(webDataStream);
                //string respFromServer = respStreamReader.ReadToEnd();

                //respStreamReader.Close();

                //htRspData = JsonConvert.DeserializeObject<Hashtable>(respFromServer);

                //if (htRspData["result"].Equals(true))
                //{
                //    iRet = BaseCom.OK;
                //}
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                                     ex.ToString());
            }

            return iRet;
        }

        // #20170616, 해피앱 스탬프 Start
        /// <summary>
        /// 해피앱 스탬프 http 통신
        /// </summary>
        /// <param name="sUrl"></param>
        /// <param name="htReqData"></param>
        /// <param name="htRspData"></param>
        /// <returns></returns>
        public int HttpJsonPOST_SendReceiveForStamp(string sUrl, Hashtable htReqData, ref Hashtable htRspData)
        {
            int iRet = BaseCom.NG;
            string sRespString = string.Empty;

            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sUrl);

                string sSendJsonData = JsonConvert.SerializeObject(htReqData);
                UserLog.WriteLogFile(UserCom.LOG_SOCK,
                                     UserCom.INFO_LEVEL,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // project name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // class name (class name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // function name (function name (함수명))
                                     sSendJsonData);

                byte[] reqByte = Encoding.UTF8.GetBytes(sSendJsonData);

                req.Method = "post";
                req.ContentType = "application/json";
                req.ContentLength = reqByte.Length;
                //#20171117 해피앱 스탬프 timeout 설정 start
                req.Timeout = 3000;
                //#20171117 해피앱 스탬프 timeout 설정 end

                // create our stream to send
                Stream webDataStream = req.GetRequestStream();
                webDataStream.Write(reqByte, 0, reqByte.Length);

                // get thre response from our stream
                
                WebResponse resp = req.GetResponse();
                webDataStream = resp.GetResponseStream();

                // convert the result into a string
                StreamReader respStreamReader = new StreamReader(webDataStream);
                string respFromServer = respStreamReader.ReadToEnd();

                respStreamReader.Close();

                UserLog.WriteLogFile(UserCom.LOG_SOCK,
                                     UserCom.INFO_LEVEL,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,      // project name (프로젝트명)
                                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." +  // class name (class name (클래스명))
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",                // function name (function name (함수명))
                                     respFromServer);

                htRspData = JsonConvert.DeserializeObject<Hashtable>(respFromServer);

                if (htRspData["result"].Equals("00"))
                {
                    iRet = BaseCom.OK;
                }
                
            }
            catch (Exception ex)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                     System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                     System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                                     ex.ToString());
            }

            return iRet;
        }
        // #20170616, 해피앱 스탬프 End

        //contentType 에 따른 HTTP Post 전송, girak.kim , 2017.09.11

        public static bool CheckValidationResult(object sender, X509Certificate certficate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        }


        #region  HTTP Post 전송

        //#20170911.001, Http post 통신 추가 start;girak.kim;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sUrl">경로</param>
        /// <param name="sContentType">전송 컨텐츠 타입</param>
        /// <param name="sReqString">전송 데이타</param>
        /// <param name="sRespData">결과 데이타</param>
        /// <returns></returns>
        public int HttpPOST_SendReceive(string sUrl, string sContentType, string sReqString, ref string sRespData)
        {
            int iRet = BaseCom.NG;

            string result = "";
            int nConnecLimit = 200;

            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream reqStream = null;

            try
            {
                ServicePointManager.DefaultConnectionLimit = nConnecLimit;//동시 연결
                if (sUrl.StartsWith("https", StringComparison.OrdinalIgnoreCase))//ssl 일 경우 인증서 무시
                {
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                }

                Uri uri = new Uri(sUrl);

                request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = "POST";
                request.Timeout = 30000;//30sec
                request.ContentType = sContentType;// "text/xml";// "text/xml; encoding='UTF-8'";

                //request.KeepAlive = false;

                byte[] bData = System.Text.Encoding.UTF8.GetBytes(sReqString);
                request.ContentLength = bData.Length;

                reqStream = request.GetRequestStream();
                reqStream.Write(bData, 0, bData.Length);
                reqStream.Close();

                response = (HttpWebResponse)request.GetResponse();

                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                result = sr.ReadToEnd().Trim();
                sr.Close();

                sRespData = result;
                iRet = BaseCom.OK;

            }
            catch (System.Threading.ThreadAbortException e)
            {
                //e.Message
                // System.Threading.Thread.ResetAbort();
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                                    System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                                    System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                                    e.ToString());
            }
            catch (WebException e)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                          System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                          System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                          e.ToString());

                if (e.Status == WebExceptionStatus.ProtocolError)
                {
                    // (HttpWebResponse)e.Response).StatusCode;
                    //(HttpWebResponse)e.Response).StatusDescription;
                }
                //throw new Exception(e.ToString());
            }
            catch (Exception e)
            {
                UserLog.WriteLogFile(UserCom.LOG_ERROR,
                          System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                          System.Reflection.MethodBase.GetCurrentMethod().Name + "()",
                          e.ToString());
                //throw new Exception(e.ToString());
            }
            finally
            {
                if (response != null) response.Close();
                if (request != null) request.Abort();
            }

            sRespData = result;
            return iRet;

        }

        //#20170911.001, Http post 통신 추가 end;girak.kim;
        #endregion
    }
}
