﻿using BaSys40.Utils.ResultHandling;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace oneM2MClient.Client.Bindings
{
    public class HttpBinding : IClient
    {
        private static HttpClient httpClient;
        private bool isAlive = false;

        public ClientFactory.Protocol Protocol => ClientFactory.Protocol.Http;

        public static void ConfigureHttpClient()
        {
            httpClient = new HttpClient(
                new HttpClientHandler
                {
                    MaxConnectionsPerServer = 100,                    
                    UseProxy = false
                });
        }

        public Result<Response> Send(Request request)
        {
            if (request == null)
                return new Result<Response>(new ArgumentNullException("request"));

            string rqi = request.GetHashCode().ToString();
            request.RequestIdentifier(rqi);

            HttpRequest requestHelper = new HttpRequest(request);
            requestHelper.Query.Remove(oneM2M.Name.RESOURCE_TYPE);

            string uri = requestHelper.RequestPath + GetQueryString(requestHelper.Query);

            HttpRequestMessage requestMessage = new HttpRequestMessage();
            requestMessage.RequestUri = new Uri(uri);
            requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(requestHelper.AcceptMIME));

            AddHeader(requestMessage.Headers, requestHelper.Header);

            oneM2M.Operation op = (oneM2M.Operation)requestHelper.Method;
            switch (op)
            {
                case oneM2M.Operation.CREATE:
                    requestMessage.Method = HttpMethod.Post;
                    requestMessage.Content = new StringContent(requestHelper.Body);

                    var contentType = new MediaTypeHeaderValue(requestHelper.ContentMIME);
                    contentType.Parameters.Add(new NameValueHeaderValue(oneM2M.Name.RESOURCE_TYPE, request.RequestPrimitive.Ty.Value.ToString()));
                    requestMessage.Content.Headers.ContentType = contentType;
                    break;

                case oneM2M.Operation.RETRIEVE:
                    requestMessage.Method = HttpMethod.Get;
                    break;

                case oneM2M.Operation.UPDATE:
                    requestMessage.Method = HttpMethod.Put;
                    requestMessage.Content = new StringContent(requestHelper.Body, Encoding.Default, requestHelper.ContentMIME);
                    break;

                case oneM2M.Operation.DELETE:
                    requestMessage.Method = HttpMethod.Delete;
                    break;

                case oneM2M.Operation.NOTIFY:
                    requestMessage.Method = HttpMethod.Post;
                    break;
                default:
                    return new Result<Response>(new InvalidOperationException("Invalid Operation: " + op));
            }
            try
            {
                var task = Task.Run(() => httpClient.SendAsync(requestMessage));
                bool success = task.Wait(request.MillisecondsTimeout);
                if (success && task.Result != null)
                {
                    HttpResponse response = new HttpResponse(task.Result);
                    if (response.OriginalHttpResponseMessage.IsSuccessStatusCode)
                    {
                        if (response.RequestIdentifier == rqi)
                            return new Result<Response>(true, response);
                        else
                            return new Result<Response>(false, response, new Message(MessageType.Error, "Response-Id: '" + response.RequestIdentifier + "' does not match Request-Id: '" + rqi + "'"));
                    }
                    else
                    {
                        StringBuilder errorMsg = new StringBuilder();
                        errorMsg.Append("Http-Response: " + (int)response.OriginalHttpResponseMessage.StatusCode + " - " + response.OriginalHttpResponseMessage.ReasonPhrase + " || ");
                        errorMsg.Append("oneM2M-Response: ").Append(response.ResponseStatusCode + " - ").Append(response.ErrorMessage + " ").Append(response.ResponseBody);
                        return new Result<Response>(false, response, new Message(MessageType.Error, errorMsg.ToString(), ((int)response.OriginalHttpResponseMessage.StatusCode).ToString()));
                    }
                }
                else
                    return new Result<Response>(false, new Message(MessageType.Error, "Error getting response from host", ((int)HttpStatusCode.BadGateway).ToString()));
            }
            catch (Exception e)
            {
                string msg = e.Message + ((e.InnerException != null) ? " - InnerException: " + e.InnerException.Message : string.Empty);
                return new Result<Response>(false, new Message(MessageType.Error, msg, ((int)HttpStatusCode.InternalServerError).ToString()));
            }
        }

        protected void AddHeader(HttpRequestHeaders headers, Dictionary<string, List<string>> dic)
        {
            foreach (var entry in dic)
            {
                string key = HttpMapping.Header.map(entry.Key);
                string value = HttpRequest.ConcatQuery(entry.Value);
                headers.Add(key, value);
            }
        }

        private string GetQueryString(Dictionary<string, List<string>> dic)
        {
            if (dic != null && dic.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("?");
                int count = 1;
                foreach (var entry in dic)
                {
                    string key = entry.Key;
                    string value = HttpRequest.ConcatQuery(entry.Value);
                    sb.Append(key + "=" + value);
                    if (count != dic.Count)
                        sb.Append("&");
                    count++;
                }
                return sb.ToString();
            }
            else
                return string.Empty;
        }

        public void Start()
        {
            ConfigureHttpClient();   
            isAlive = true;
        }

        public void Stop()
        {
            httpClient.Dispose();
            isAlive = false;
        }

        public bool IsAlive
        {
            get
            {
                return isAlive;
            }
        }

        
    }
}
