using Newtonsoft.Json;
using ServiceCenter.Extensions;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Net;
using System.Text;

namespace ServiceCenter.WebApi
{
    public class APICaller
    {
        private class Result
        {
            public bool Succsess;
            public string Exception;
            public object Data;
        }

        private static ConcurrentDictionary<string, Result> Results = new ConcurrentDictionary<string, Result>();

        public static T CallApi2<T>(string url, object parameter, string type = "POST")
        {
            var content = JsonConvert.SerializeObject(parameter);
            var result = HttpApi(url, content, type);
            return JsonConvert.DeserializeObject<T>(result);
        }

        public static T CallApi<T>(string url, object parameter, string type = "Post")
        {
            var content = JsonConvert.SerializeObject(parameter);
            var key = url + content;
            if (Results.ContainsKey(key))
            {
                var res = Results[key];
                if (res == null) throw new Exception("接口调用中");

                try
                {
                    if (!res.Succsess) throw new Exception(res.Exception);

                    return (T)res.Data;
                }
                finally
                {
                    Results.Remove(key, out res);
                }
            }
            else
            {
                Results[key] = null;
                var task = Task.Run(() =>
                 {
                     var res = new Result();
                     try
                     {
                         var result = HttpApi(url, content, type);
                         res.Data = JsonConvert.DeserializeObject<T>(result);
                         res.Succsess = true;
                     }
                     catch (Exception ex)
                     {
                         res.Exception = ex.Message;
                     }
                     finally
                     {
                         Results[key] = res;
                     }
                 });
                task.Wait(50);
                if (task.IsCompleted)
                {
                    return CallApi<T>(url, parameter, type);
                }
                else
                {
                    throw new Exception("接口调用中");
                }
            }
        }

        private static string HttpApi(string url, string jsonstr, string type)
        {
            LogHub.Publish($"D:\\WCSLogs\\{DateTime.Now.yyyyMMdd()}\\接口调用日志", $"调用日志.txt", $"{DateTime.Now.yyyyMMddhhmmssf()}--[{Thread.CurrentThread.ManagedThreadId}]--接口{url}传参---------{JsonConvert.SerializeObject(jsonstr)}\n");
            var sw = new Stopwatch();
            sw.Start();
            Encoding encoding = Encoding.UTF8;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);//webrequest请求api地址
            request.Timeout = 60000;//连接超时
            request.ReadWriteTimeout = 3600000;//读写超时
            request.Accept = "text/html,application/xhtml+xml,*/*";
            request.ContentType = "application/json";
            request.Method = type.ToUpper().ToString();//get或者post
            byte[] buffer = encoding.GetBytes(jsonstr);
            request.ContentLength = buffer.Length;
            request.GetRequestStream().Write(buffer, 0, buffer.Length);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
            {
                var res = reader.ReadToEnd();
                sw.Stop();
                LogHub.Publish($"D:\\WCSLogs\\{DateTime.Now.yyyyMMdd()}\\接口调用日志", $"调用日志.txt", $"{DateTime.Now.yyyyMMddhhmmssf()}--[{Thread.CurrentThread.ManagedThreadId}]--接口{url}调用耗时:{sw.ElapsedMilliseconds}---------{JsonConvert.SerializeObject(res)}\n");
                return res;
            }
        }
    }
}
