using System.Net;
using RestSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace InABox.Clients
{
    internal static class RestClientCache
    {
        private static readonly Dictionary<string, Tuple<string, bool, DatabaseInfo>> _cache = new Dictionary<string, Tuple<string, bool, DatabaseInfo>>();
        
        public static string URL(string host)
        {
            if (_cache.TryGetValue(host, out var value))
                return value.Item1;
            return "";
        }

        public static bool IsSecure(string host)
        {
            if (_cache.TryGetValue(host, out var value))
                return value.Item2;
            return false;
        }
        
        public static DatabaseInfo Info(string host)
        {
            if (_cache.TryGetValue(host, out var value))
                return value.Item3;
            return new DatabaseInfo();
        }
            
        private static bool Check(string host, bool https)
        {
            var uri = new Uri($"http://{host}");
            string schema = https ? "https" : "http";
            var url = $"{schema}://{uri.Host}:{uri.Port}";
            var req = new RestRequest("/info", Method.Get) { Timeout = TimeSpan.FromSeconds(20) };
            var res = new RestClient(new Uri(url)).Execute(req);
            if ((res.StatusCode != HttpStatusCode.OK) || (res.ErrorException != null))
                return false;
            try
            {
                var response = Core.Serialization.Deserialize<InfoResponse>(res.Content);
                if (response?.Info == null)
                    return false;
                _cache[host] = new Tuple<string, bool, DatabaseInfo>(url, https, response.Info);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        
        public static string Check(string server)
        {
            var host = server.Split(new[] { "://" }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();
            
            if (string.IsNullOrWhiteSpace(host))
                return "";
            
            if (_cache.TryGetValue(host, out var cached))
                return cached.Item1;
            
            if (!Check(host, true))
                Check(host, false);
            
            return _cache.TryGetValue(host, out var check) ? check.Item1 : "";

        }
    }
}