using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace AssistClient.Utils
{
    internal static class HttpUtil
    {
        //读取请求数据
        public static string getPostData(HttpListenerRequest request)
        {
            if (!request.HasEntityBody)
                return null;

            string result;
            using (Stream inputStream = request.InputStream)
            {
                using (StreamReader streamReader = new StreamReader(inputStream, Encoding.UTF8))
                    result = streamReader.ReadToEnd();
            }
            return result;
        }

        /// <summary>
        /// POST请求接口调用
        /// </summary>
        /// <param name="url"></param>
        /// <param name="json"></param>
        /// <returns></returns>
        public static void post(string url, string json, Action<JObject> callBack = null)
        {
            System.Threading.ThreadPool.QueueUserWorkItem(
                new WaitCallback(o =>
                {
                    var data = (JObject)o;
                    if (callBack == null)
                        postSync(data["url"].ToString(), data["json"].ToString(), false);
                    else
                        callBack(postSync(data["url"].ToString(), data["json"].ToString()));
                }),
                JObject.FromObject(new { url, json })
            );
        }
        //HttpWebRequest方式
        public static JObject postSync2(string url, string json, bool recvResp = true)
        {
            JObject resp = new JObject();
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                //request.ContentType = "application/x-www-form-urlencoded";
                request.ContentType = "application /json";
                StreamWriter requestWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.UTF8);
                requestWriter.Write(json);
                requestWriter.Flush();
                requestWriter.Close();

                if (recvResp)
                {
                    WebResponse webResponse = request.GetResponse();
                    Stream webStream = webResponse.GetResponseStream();
                    StreamReader responseReader = new StreamReader(webStream);
                    resp.Add("data", responseReader.ReadToEnd());
                    resp.Add("success", true);
                }
                else
                {
                    request.GetResponse().Close();//必需调用此GetResponse后上面的write才会发送出去，操 
                    resp.Add("data", "");
                    resp.Add("success", true);
                }
            }
            catch (Exception ex)
            {
                resp.Add("success", false);
                resp.Add("data", ex.Message);
            }

            return resp;
        }
        //HttpClient方式
        public static JObject postSync(string url, string json, bool recvResp = true, bool isJson = true)
        {
            JObject resp = new JObject();
            try
            {
                HttpClient http = new HttpClient();
                StringContent dataContent;
                //第一种方式：data是json格式 
                if (isJson)
                    dataContent = new StringContent(json, System.Text.Encoding.UTF8, "application/json"); // {"PageNum":"1","PageSIze":"20","info":"311011500300661"}
                else
                {
                    // 第二种方式：form表单提交 内容post 提交都在StringContent请求body中添加
                    string lsUrlEncodeStr = json2Params(JObject.Parse(json));
                    dataContent = new StringContent(lsUrlEncodeStr, System.Text.Encoding.UTF8, "application/x-www-form-urlencoded"); //PageNum=1&PageSize=20&info=311011500300661
                }

                http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "token");
                var taskstr = http.PostAsync(url, dataContent).Result.Content.ReadAsStringAsync();
                API.OutputDebugString("wlq postSync:url=" + url + ";resp=" + taskstr.Result);
                //读取返回数据 
                //return taskstr.Result;
                if (recvResp)
                {
                    resp.Add("data", taskstr.Result);
                    resp.Add("success", true);
                }
                else
                {
                    resp.Add("data", "");
                    resp.Add("success", true);
                }
            }
            catch (Exception ex)
            {
                resp.Add("success", false);
                resp.Add("data", ex.Message);
            }

            return resp;
        }
        /// <summary>
        /// 向HTTP连接写入数据
        /// </summary>
        /// <param name="resp">HttpListenerContext.Response</param>
        /// <param name="data"></param>
        /// <returns>如果连接关闭返回 false</returns>
        public static bool writeToHttpContext(HttpListenerResponse resp, byte[] dataBuff)
        {
            try
            {
                resp.OutputStream.Write(dataBuff, 0, dataBuff.Length);
                resp.OutputStream.Flush();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public static bool writeToHttpContext_json(HttpListenerResponse resp, string json)
        {
            byte[] buff = Encoding.UTF8.GetBytes(json);
            resp.ContentType = "application/json";
            resp.ContentEncoding = Encoding.UTF8;
            return writeToHttpContext(resp, buff);
        }
        public static bool writeToHttpContext_text(HttpListenerResponse resp, string text)
        {
            byte[] buff = Encoding.UTF8.GetBytes(text);
            resp.ContentType = "application/text";
            resp.ContentEncoding = Encoding.UTF8;
            return writeToHttpContext(resp, buff);
        }
        private static string json2Params(JObject json)
        {
            string result = "";
            IEnumerable<JProperty> properties = json.Properties();
            foreach (JProperty item in properties)
            {
                result += item.Name.ToString() + "=" + item.Value.ToString() + "&";
                // item.Name 为 键
                // item.Value 为 值
            }

            result = result.Substring(0, result.Length - 1);
            //string result1 = WebUtility.UrlEncode(result);//转义字符大写
            ////string result2 = HttpUtility.UrlEncode(result);//转义字符小写 
            return result;
        }

        /// <summary>  
        /// 获取文件对应MIME类型  
        /// </summary>  
        /// <param name="fileExtention">文件扩展名,如.jpg</param>  
        /// <returns></returns>  
        public static string GetContentType(string fileExtention)
        {
            if (string.Compare(fileExtention, ".html", true) == 0 || string.Compare(fileExtention, ".htm", true) == 0)
                return "text/html;charset=utf-8";
            else if (string.Compare(fileExtention, ".js", true) == 0)
                return "application/javascript";
            else if (string.Compare(fileExtention, ".css", true) == 0)
                return "text/css";
            else if (string.Compare(fileExtention, ".png", true) == 0)
                return "image/png";
            else if (string.Compare(fileExtention, ".jpg", true) == 0 || string.Compare(fileExtention, ".jpeg", true) == 0)
                return "image/jpeg";
            else if (string.Compare(fileExtention, ".gif", true) == 0)
                return "image/gif";
            else if (string.Compare(fileExtention, ".swf", true) == 0)
                return "application/x-shockwave-flash";
            else if (string.Compare(fileExtention, ".bcmap", true) == 0)
                return "image/svg+xml";
            else if (string.Compare(fileExtention, ".properties", true) == 0)
                return "application/octet-stream";
            else if (string.Compare(fileExtention, ".map", true) == 0)
                return "text/plain";
            else if (string.Compare(fileExtention, ".svg", true) == 0)
                return "image/svg+xml";
            else if (string.Compare(fileExtention, ".pdf", true) == 0)
                return "application/pdf";
            else if (string.Compare(fileExtention, ".txt", true) == 0)
                return "text/*";
            else if (string.Compare(fileExtention, ".dat", true) == 0)
                return "text/*";
            else
                return "application/octet-stream";//application/octet-stream

        }
    }

}
