using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;
namespace Helper
{
    /// <summary>
    /// 网络编程帮助类
    /// </summary>
    [ComVisible(true)]
    public static class HttpHelper
    {
        public static int TimeOut { get; set; }
        public static string Proxy { get; set; }
        public static bool UseProxy { get; set; }
        public static long Count { get; set; }
        [DllImport("wininet.dll")]
        public extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
        ///<summary>
        /// 查看网络是否连接到公网
        ///</summary>
        ///<returns>返回Ture：可以连接到Internet，False则连接不上</returns>
        public static bool IsConnectedToInternet
        {
            get
            {
                int Desc;
                return InternetGetConnectedState(out Desc, 0);
            }
        }
        public static void SetSSL()
        {
            try
            {
                ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
            }
            catch (Exception)
            { }
            try
            {
                ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
            }
            catch (Exception)
            { }
        }
        /// <summary>
        /// 解决Error"基础连接已经关闭: 未能为SSL/TLS 安全通道建立信任关系。"
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="sslPolicyErrors"></param>
        /// <returns></returns>
        public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
        class HttpClient : WebClient
        {
            public void GetFile(string path, string url)
            {
                if (url == string.Empty)
                { throw new WebException("下载地址为空"); }
                base.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 OPR/48.0.2685.52";
                DownloadFile(url, path);
            }
        }
        /// <summary>
        /// get请求
        /// </summary>
        /// <param name="urlstr">url</param>
        /// <returns></returns>
        public static string Get(string url, string referer = null)
        {
            return Get(url, Encoding.UTF8, referer);
        }
        /// <summary>
        /// get请求
        /// </summary>
        /// <param name="url">url</param>
        /// <returns></returns>
        public static string Get(string url, Encoding en, string referer = null)
        {
            SetSSL();
            string message = string.Empty;
            string[] urls = { url.Replace("https://", "http://"), url.Replace("http://", "https://") };
            foreach (string item in urls)
            {
                try
                {
                    if (!url.Contains("http"))
                    { return File.ReadAllText(url); }
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(item);
                    req.Accept = "text/html, application/xhtml+xml, */*";
                    req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36";
                    //req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)";
                    req.KeepAlive = true;
                    if (!string.IsNullOrEmpty(referer))
                    {
                        req.Referer = referer;
                    }
                    req.Timeout = TimeOut == 0 ? 10000 : TimeOut;
                    req.ProtocolVersion = HttpVersion.Version11;
                    ServicePointManager.Expect100Continue = false;
                    HttpWebResponse response = (HttpWebResponse)req.GetResponse();
                    Stream responseStream = response.GetResponseStream();
                    StreamReader reader = new StreamReader(responseStream, en);
                    message = reader.ReadToEnd();
                    Count += message.Length;
                    reader.Close();
                    responseStream.Close();
                    break;
                }
                catch (Exception ex)
                {
                    message = ex.Message;
                    throw;
                }
            }
            return ConvertEx.UnicodeToString(message);
        }
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="path">目录</param>
        /// <param name="url">下载地址</param>
        public static void Down(string path, string url)
        {
            SetSSL();
            HttpClient Client = new HttpClient();
            try
            { Client.GetFile(path.Replace("\\\\", "\\"), url); }
            catch (Exception err)
            { throw new Exception("void Down(string,string)发生了异常:" + err.Message); }
        }
        public static string Redirect(string url)
        {
            SetSSL();
            try
            {
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                req.Method = "HEAD";
                req.AllowAutoRedirect = false;
                req.Timeout = TimeOut == 0 ? 10000 : TimeOut;
                HttpWebResponse myResp = (HttpWebResponse)req.GetResponse();
                if (myResp.StatusCode == HttpStatusCode.Redirect)
                { return myResp.GetResponseHeader("Location"); }
            }
            catch (Exception)
            { }
            return url;
        }

        /// <summary>
        /// 检查url链接是否有效
        /// </summary>
        /// <param name="strUri"></param>
        /// <returns></returns>
        public static bool CheckUri(string url)
        {
            if (string.IsNullOrWhiteSpace(url))
            { return false; }
            SetSSL();
            try
            {
                if (url.Contains("http"))
                {
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                    req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";
                    req.Method = "GET";
                    req.Timeout = TimeOut == 0 ? 10000 : TimeOut;
                    HttpWebResponse myHttpWebResponse = (HttpWebResponse)req.GetResponse();
                    if (myHttpWebResponse.StatusCode == HttpStatusCode.OK)
                    {
                        myHttpWebResponse.Close();
                        return true;
                    }
                }
                else { return File.Exists(url); }
                return false;
            }
            catch (Exception)
            {
                return false;
            }
        }
        /// <summary>
        /// 指定Post地址使用Get 方式获取全部字符串
        /// </summary>
        /// <param name="url">请求后台地址</param>
        /// <returns></returns>
        public static string Post(string url, Dictionary<string, string> dic)
        {
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            #region 添加Post 参数
            StringBuilder builder = new StringBuilder();
            int i = 0;
            foreach (var item in dic)
            {
                if (i > 0)
                    builder.Append("&");
                builder.AppendFormat("{0}={1}", item.Key, item.Value);
                i++;
            }
            byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
            req.ContentLength = data.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            #endregion
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return ConvertEx.UnicodeToString(result);
        }
    }
}