/*
 * 由SharpDevelop创建。
 * 用户： gwang
 * 日期: 2016/5/3
 * 时间: 17:20
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
//using CSharpUtil.RSA;
namespace CSharpUtil.Net
{
    /// <summary>
    /// Http辅助类.
    /// </summary>
    public class HttpHelper
    {
        /// <summary>
        /// 自定义异常,编码不合约定(Get=>Base64,Post=>deflate)
        /// </summary>
        class EncodeException : Exception
        {
            public EncodeException()
                : base("编码")
            {

            }
        }
        /// <summary>
        /// 自定义的User-Agent
        /// </summary>
        const string userAgent = "WebRequest/mail@wanggangzero.cn";

        private static HttpHelper mInst = mInst ?? new HttpHelper();
        /// <summary>
        /// 单例
        /// </summary>
        public static HttpHelper Instance { get => mInst; }

        private IWebProxy mProxy = new WebProxy();
        /// <summary>
        /// 可以指定代理服务器
        /// </summary>
        public IWebProxy Proxy { get => mProxy; set => mProxy = value; }

        public string Post(string url, string data) => mWebRequest(url, data, "POST", Encoding.UTF8);

        private HttpWebRequest mGetWebRequest(string url, string method)
        {
            var webReq = (HttpWebRequest)WebRequest.Create(new Uri(url));
            webReq.Method = method;
            webReq.KeepAlive = true;
            webReq.UserAgent = userAgent;
            webReq.Proxy = mProxy;
            return webReq;
        }
        private string mWebRequest(string url, string data, string method, Encoding encode)
        {
            var ret = string.Empty;
            var getUrl = (method.ToUpper() == "GET") ? url + "?" + data : url;
            var webReq = mGetWebRequest(getUrl, method);
            if (method.ToUpper() == "POST")
            {       // 写post流
                webReq.ServicePoint.Expect100Continue = false;   // Post优化,去掉问答流程,提速,避免一些服务器不支持.		
                try
                {
                    using (var nstream = webReq.GetRequestStream())
                    {
                        var byteArray = encode.GetBytes(data);
                        nstream.Write(byteArray, 0, byteArray.Length);
                    }
                }
                catch (Exception e)
                {
                    return "net fail";
                }
            }
            // 读取返回值
            using (var response = (HttpWebResponse)webReq.GetResponse())
            using (var sr = new StreamReader(response.GetResponseStream(), encode))
            {
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    return response.StatusDescription;
                }
                ret = sr.ReadToEnd();
            }

            return ret;
        }

        #region ` 自定义传输模式 post=>defalte,get=>base64  `
        /// <summary>
        /// 发送deflate
        /// </summary>
        /// <param name="url"></param>
        /// <param name="data"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        public string PostDeflate(string url, string data, Encoding encode) => MyWebRequest(url, data, "POST", encode);

        public string GetBase64(string url, string data, Encoding encode) => MyWebRequest(url, data, "GET", encode);

        private string MyWebRequest(string url, string data, string method, Encoding encode)
        {
            var ret = string.Empty;

            var getUrl = (method.ToUpper() == "GET") ? url + "?" + Convert.ToBase64String(encode.GetBytes(data)) : url;

            var webReq = (HttpWebRequest)WebRequest.Create(new Uri(getUrl));
            webReq.Method = method;
            webReq.KeepAlive = true;
            webReq.UserAgent = userAgent;
            webReq.Proxy = mProxy;
            if (method.ToUpper() == "POST")
            {       // 写post流
                webReq.ContentType = "application/octet-stream";  // 注意这里不使用deflate以免中间环节意外解压
                webReq.ServicePoint.Expect100Continue = false;   // Post优化,去掉问答流程,提速,避免一些服务器不支持.		
                using (Stream nstream = webReq.GetRequestStream())
                {
                    var byteArray = CompressUtil.Deflate(encode.GetBytes(data));
                    nstream.Write(byteArray, 0, byteArray.Length);
                }
            }
            // 读取返回值
            using (var response = (HttpWebResponse)webReq.GetResponse())
            {
                if (method.ToUpper() == "GET")
                {
                    using (var sr = new StreamReader(response.GetResponseStream(), encode))
                    {
                        ret = encode.GetString(Convert.FromBase64String(sr.ReadToEnd()));
                    }
                }
                else
                {
                    ret = encode.GetString(CompressUtil.InFlate(response.GetResponseStream()));
                }
            }

            return ret;
        }

        #endregion


        #region `   签名   `
        ///// <summary>
        ///// http参数签名
        ///// </summary>
        ///// <param name="dic"></param>
        ///// <param name="privKeyFileName"></param>
        ///// <returns></returns>
        //public static string Sign(IDictionary<string, string> dic, string privKeyFileName)
        //{
        //    var queryStr = getQueryString(dic);

        //    return RSAUtil.RSASign(queryStr, privKeyFileName);

        //}
        /// <summary>
        /// 将参数数组组装成URLQuerystring.
        /// </summary>
        /// <param name="parameters"></param>
        /// <param name="sorted"></param>
        /// <returns></returns>
        public static string getQueryString(IDictionary<string, string> parameters, bool sorted = true)
        {
            return string.Join("&", (from kv in (sorted ? parameters.OrderBy(kv => kv.Key) : parameters.AsEnumerable()) select kv.Key + "=" + kv.Value).ToArray());
        }

        #endregion
    }

}
