using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Bailun.DC.Common
{
    public class HttpHelper
    {
        /// <summary>
        /// 向远程Url Post/Get数据类
        /// </summary>
        public class NetHelper
        {
            public enum RequestType
            {
                GET,
                POST
            }

            /// <summary>
            /// 设置header信息
            /// </summary>
            /// <param name="header"></param>
            /// <param name="name"></param>
            /// <param name="value"></param>
            public static void SetHeaderValue(WebHeaderCollection header, string name, string value)
            {
                var property = typeof(WebHeaderCollection).GetProperty("InnerCollection",
                    System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                if (property != null)
                {
                    var collection = property.GetValue(header, null) as NameValueCollection;
                    collection[name] = value;
                }
            }

            /// <summary>
            /// 通过代理访问网络
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            public static string Request(string url, RequestType type = RequestType.GET, string data = null, string host = null)
            {
                HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(url); //建立HttpWebRequest對象
                httpRequest.Timeout = 600000; //定義服務器超時時間  
                httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36";
                httpRequest.Accept = "*";

                if (!string.IsNullOrEmpty(host))
                {
                    SetHeaderValue(httpRequest.Headers, "Host", host);
                }
                switch (type)
                {
                    case RequestType.GET:
                        httpRequest.ContentType = "text/html; charset=UTF-8";
                        httpRequest.Method = "GET";
                        break;
                    case RequestType.POST:
                        httpRequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
                        httpRequest.Method = "POST";

                        // 通过流写入请求数据
                        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data); // 编码形式按照个人需求来设置
                        httpRequest.ContentLength = bytes.Length;
                        Stream requestStream = httpRequest.GetRequestStream();
                        requestStream.Write(bytes, 0, bytes.Length);
                        requestStream.Close(); // 不要忘记关闭流 
                        break;
                    default:
                        httpRequest.ContentType = "text/html; charset=UTF-8";
                        break;
                }

                StringBuilder content = new StringBuilder(); // 
                try
                {
                    HttpWebResponse hwrs = (HttpWebResponse)httpRequest.GetResponse(); //取得回應 
                    Stream s = hwrs.GetResponseStream(); //得到回應的流對象 
                    StreamReader sr = new StreamReader(s, Encoding.UTF8); //以UTF-8編碼讀取流 

                    while (sr.Peek() != -1) //每次讀取一行,直到 
                    { //下一個字節沒有內容 
                        content.Append(sr.ReadLine()); //返回為止 
                    } //  
                    s.Dispose();
                    sr.Close();
                    hwrs.Close();

                    System.Threading.Thread.Sleep(10);
                }
                catch (Exception e)
                {

                }

                return content.ToString(); //返回得到的字符串 
            }

            //张剑峰 2018年3月7日10:38:49
            public static string HttpPostJson(string url, string data = null, string host = null)
            {
                HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(url); //建立HttpWebRequest對象
                httpRequest.Timeout = 600000; //定義服務器超時時間
                httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36";
                httpRequest.Accept = "*";

                if (!string.IsNullOrEmpty(host))
                {
                    SetHeaderValue(httpRequest.Headers, "Host", host);
                }
                httpRequest.ContentType = "application/json";
                httpRequest.Method = "POST";

                // 通过流写入请求数据
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data); // 编码形式按照个人需求来设置
                httpRequest.ContentLength = bytes.Length;
                Stream requestStream = httpRequest.GetRequestStream();
                requestStream.Write(bytes, 0, bytes.Length);
                requestStream.Close(); // 不要忘记关闭流 

                StringBuilder content = new StringBuilder(); // 
                try
                {
                    HttpWebResponse hwrs = (HttpWebResponse)httpRequest.GetResponse(); //取得回應 
                    Stream s = hwrs.GetResponseStream(); //得到回應的流對象 
                    StreamReader sr = new StreamReader(s, Encoding.UTF8); //以UTF-8編碼讀取流 

                    while (sr.Peek() != -1) //每次讀取一行,直到 
                    { //下一個字節沒有內容 
                        content.Append(sr.ReadLine()); //返回為止 
                    } //  
                    s.Dispose();
                    sr.Close();
                    hwrs.Close();

                    System.Threading.Thread.Sleep(10);
                }
                catch (Exception e)
                {

                }

                return content.ToString(); //返回得到的字符串 
            }

            /// <summary>
            /// 获取网址域名
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            public static string GetDomain(string url)
            {
                Regex reg = new Regex(@"(?is)((http|https)://[^/]+)/");
                var m = reg.Match(url);
                if (m.Success)
                {
                    return m.Groups[0].Value;
                }
                return string.Empty;
            }

            /// <summary>
            /// 获取网址域名
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            public static string GetRelativeUrl(string url)
            {
                Regex reg = new Regex(@"(?is)(http|https)://[^/]+(/.*)");
                var m = reg.Match(url);
                if (m.Success)
                {
                    return m.Groups[2].Value;
                }
                return url;
            }


            /// <summary>  
            /// 向Url发送post请求  
            /// </summary>  
            /// <param name="postData">发送数据</param>  
            /// <param name="uriStr">接受数据的Url</param>  
            /// <returns>返回网站响应请求的回复</returns>  
            public static string HttpPost(string uriStr, string postData)
            {
                return GetPageContent(uriStr, postData);
            }

            /// <summary>  
            /// 向Url发送post请求  
            /// </summary>  
            /// <param name="postData">发送数据</param>  
            /// <param name="uriStr">接受数据的Url</param>  
            /// <returns>返回网站响应请求的回复</returns>  
            public static string HttpPost(string uriStr, NameValueCollection postData, int errors = 0, string host = "", int timeout = 0)
            {
                StringBuilder tempData = new StringBuilder();
                if (postData != null)
                {
                    foreach (string key in postData.AllKeys)
                    {
                        tempData.AppendFormat("{0}={1}&", key, postData.GetValues(key).GetValue(0));
                    }
                    tempData = tempData.Remove(tempData.Length - 1, 1);
                }
                return GetPageContent(uriStr, tempData.ToString(), errors, host, timeout);
            }

            private static string GetPageContent(string uriStr, string tempData, int errors = 0, string host = "", int timeout = 0)
            {
                //超时提醒
                try
                {
                    HttpWebRequest requestScore = (HttpWebRequest)WebRequest.Create(uriStr);
                    byte[] data = Encoding.UTF8.GetBytes(tempData);

                    requestScore.Method = "POST";
                    requestScore.KeepAlive = false;
                    requestScore.AllowAutoRedirect = true;
                    requestScore.ContentType = "application/x-www-form-urlencoded";
                    requestScore.UserAgent = "Ocean/NET-SDKClient";
                    requestScore.ContentLength = data.Length;


                    if (timeout <= 0)
                        requestScore.KeepAlive = true;
                    else
                        requestScore.Timeout = timeout * 1000;

                    if (!string.IsNullOrEmpty(host))
                    {
                        SetHeaderValue(requestScore.Headers, "Host", host);
                    }

                    Stream stream = requestScore.GetRequestStream();
                    stream.Write(data, 0, data.Length);
                    stream.Close();

                    HttpWebResponse responseSorce;
                    responseSorce = (HttpWebResponse)requestScore.GetResponse();
                    StreamReader reader = new StreamReader(responseSorce.GetResponseStream(), Encoding.UTF8);
                    string content = reader.ReadToEnd();

                    requestScore.Abort();
                    responseSorce.Close();
                    responseSorce.Close();
                    reader.Dispose();
                    stream.Dispose();
                    return content;
                }
                catch (WebException e)
                {
                    errors++;
                    if (errors <= 5)
                    {
                        System.Threading.Thread.Sleep(new Random().Next(1000, 3000));
                        return GetPageContent(uriStr, tempData, errors, host, timeout);
                    }
                }
                return string.Empty;
            }
        }
    }
}
