using Newtonsoft.Json;
using RestSharp;
using RestSharp.Validation;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;

namespace Model
{
    public static class Http
    {
        public static bool Ping(string ip)
        {
            try
            {
                using System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
                System.Net.NetworkInformation.PingReply result = ping.Send(ip, 2000);
                bool rtn = result.Status == System.Net.NetworkInformation.IPStatus.Success;
                if (rtn)
                    LogNet.log.Info(string.Format("Ping {0} OK", ip));
                else
                    LogNet.log.Info(string.Format("Ping {0} timeout", ip));
                return rtn;
            }
            catch (Exception ex)
            {
                LogNet.log.Error("Ping", ex);
                return false;
            }
        }

        public static string Get(string url)
        {
            //RestClient client = new(url) { Timeout = 60000 };
            //RestRequest request = new(Method.GET);
            //IRestResponse response = client.Execute(request);
            //string s = response.Content;
            var client = new HttpClient();
            var request = new HttpRequestMessage(HttpMethod.Get, url);
            var response =  client.SendAsync(request).Result;
            response.EnsureSuccessStatusCode();
            string s= response.Content.ReadAsStringAsync().Result;
            LogNet.log.Info($"[GET][URL:{url}][Return:{s}]");
            return FormatContent(s);
        }

        public static string Post(string url, Dictionary<string, string > param)
        {
            List<string> body = new();
            foreach (string key in param.Keys)
                body.Add(string.Format("{0}={1}", key, param[key]));
            LogNet.log.Info("[Post]URL:" + url + " Body:" + string.Join(",", body));

            RestClient client = new(url) { Timeout = 10000 };
            RestRequest request = new(Method.POST);
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
            foreach(string key in param.Keys)
                request.AddParameter(key, param[key]);
            IRestResponse response = client.Execute(request);
            string s = response.Content;
            LogNet.log.Info("Return:" + s);
            return FormatContent(s);
        }
        public static string PostJson<T>(string url, Dictionary<string, string> headers, T jsonobject, int timeout = 10000, bool wlog=true)
        {
            RestClient client = new(url) { Timeout = timeout };
            client.UseSerializer(new CustSerialize());
            
            RestRequest request = new(Method.POST);
            request.AddHeader("Content-Type", "application/json");
            if (headers != null)
            {
                foreach (var head in headers)
                {
                    request.AddHeader(head.Key, head.Value);
                }
            }
            request.AddJsonBody(jsonobject);
            IRestResponse response = client.Execute(request);
            
            string s = response.Content;
            if (wlog)
                LogNet.log.Info("Return:" + s + "," + response.ErrorMessage);
            return s;
        }
        private static string FormatContent(string s)
        {
            if (string.IsNullOrWhiteSpace(s))
            {
                return "";
            }
            else
            {
                s = s.Replace("\n", "");
                s = s.Replace("\r", "");
                while (s.IndexOf("  ") >= 0)
                    s = s.Replace("  ", " ");
                return s;
            }
        }

        public static string GetToken(string url,string username,string password)
        {
            RestClient client = new(url) { Timeout = 60000 };
            RestRequest request = new(Method.GET);
            request.AddHeader("Userid", username);
            request.AddHeader("Password", password);
            request.AddHeader("Accept", "application/json");
            request.AddHeader("Cookie", "ASP.NET_SessionId=5jxc55snxa5jtomdoutiw1mi");
            IRestResponse response = client.Execute(request);
            string s = response.Content;
            LogNet.log.Info($"[GET][URL:{url}][Return:{s}]");
            return FormatContent(s);
        }
        public static string PostWithHeader(string url, string body, Dictionary<string, string> headerMap)
        {
            //List<string> body = new();
            //foreach (string key in param.Keys)
            //    body.Add(string.Format("{0}={1}", key, param[key]));
            //string body = JsonConvert.SerializeObject(param);
            LogNet.log.Info("[Post]URL:" + url + " Body=" +body);

            RestClient client = new(url) { Timeout = 10000 };
            RestRequest request = new(Method.POST);
            //增加header
            if (headerMap != null && headerMap.Count > 0)
            {
                foreach (var head in headerMap)
                {
                    request.AddHeader(head.Key, head.Value);
                }
            }
            request.AddHeader("Content-Type", "application/json;charset=utf-8");
           
            request.AddJsonBody(body);
            IRestResponse response = client.Execute(request);
            if (response.ErrorException != null)
            {
                LogNet.log.Error("[Post]URL:" + url + " Error: " + response.ErrorException.ToString());
                throw response.ErrorException;
            }
            string s = response.Content;
            LogNet.log.Info("[Post]URL:" + url + "Return:" + s);
            return FormatContent(s);
        }

        public static string GetWithHeader(string url, Dictionary<string, string> headerMap, Dictionary<string, object> queryParams = null)
        {
            if (queryParams != null && queryParams.Count > 0)
            {
                var queryString = HttpUtility.ParseQueryString(string.Empty);
                foreach (var param in queryParams)
                {
                    queryString.Add(param.Key, param.Value?.ToString());
                }
                if (url.Contains("?"))
                    url += "&" + queryString.ToString();
                else
                    url += "?" + queryString.ToString();
            }
            LogNet.log.Info("[Get]URL:" + url);

            RestClient client = new(url) { Timeout = 10000 };
            RestRequest request = new(Method.GET);
            if (headerMap != null && headerMap.Count > 0)
            {
                foreach (var head in headerMap)
                {
                    request.AddHeader(head.Key, head.Value);
                }
            }
            IRestResponse response = client.Execute(request);
            if (response.ErrorException != null)
            {
                LogNet.log.Error("[Get]URL:" + url + " Error: " + response.ErrorException.ToString());
                throw response.ErrorException;
            }
            string s = response.Content;
            LogNet.log.Info("[Get]URL:" + url + "Return:" + s);
            return FormatContent(s);
        }
    }
    public class CustSerialize : RestSharp.Serialization.IRestSerializer
    {
        public string ContentType { get; set; } = "application/json";

        public string[] SupportedContentTypes { get; set; } = new string[] { "application/json" };

        public DataFormat DataFormat { get; set; } = DataFormat.Json;

        public T Deserialize<T>(IRestResponse response)
        {
            return JsonConvert.DeserializeObject<T>(response.Content);
        }

        public string Serialize(object obj)
        {
            return JsonConvert.SerializeObject(obj);
        }

        public string Serialize(Parameter parameter)
        {
            return JsonConvert.SerializeObject(parameter.Value);

        }
    }  
}