using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using dodohold.core;
using Spire.Pdf.Exporting.XPS.Schema;
using System.Xml.Linq;
using System.Net;
using TencentCloud.Mrs.V20200910.Models;
using static molilian.core.TkPoolCore;


namespace molilian.core
{
    public partial class ProxyNodesCore
    {


        private static string _end_point;
        static ProxyNodesCore()
        {
            _end_point = Environment.GetEnvironmentVariable("EndPoint");
        }


        private static readonly object _lockObj = new();
        private static IEnumerable<ProxyNodesDTO> _cached;
        public static WebProxy? GetOne(string node)
        {
            var list = List();
            if (!list.Any()) return null;

            var ProxyNodesDTO = list.Where(e => SelectEndPointUseProxy(e, node)).OrderBy(l => Guid.NewGuid()).FirstOrDefault();
            if (ProxyNodesDTO == null) return null;

            return new WebProxy
            {
                Address = new Uri(ProxyNodesDTO.server),
                Credentials = new NetworkCredential(ProxyNodesDTO.username, ProxyNodesDTO.password)
            };
        }
        public static WebProxy? RandomOne()
        {

            var list = List();
            if (!list.Any()) return null;
            var ProxyNodesDTO = list.Where(e => SelectEndPointUseProxy(e, string.Empty)).OrderBy(l => Guid.NewGuid()).FirstOrDefault();
            if (ProxyNodesDTO == null) return null;

            return new WebProxy
            {
                Address = new Uri(ProxyNodesDTO.server),
                Credentials = new NetworkCredential(ProxyNodesDTO.username, ProxyNodesDTO.password)
            };
        }

        private static bool SelectEndPointUseProxy(ProxyNodesDTO item, string node="")
        {
            if (!string.IsNullOrEmpty(_end_point) && !string.IsNullOrEmpty(item.end_point))
            {
                if (item.end_point != _end_point) return false;
            }
            return string.IsNullOrEmpty(node) || item.name == node;
        }
        public static IEnumerable<ProxyNodesDTO> List(bool force = false)
        {
            if (!force && _cached != null) return _cached;

            string cache_key = $"cache:proxy_nodes";
            var list = RedisHelper.Get<IEnumerable<ProxyNodesDTO>>(cache_key);
            if (force || list == null)
            {
                lock (_lockObj)
                {
                    list = new DBContext.Table("proxy_nodes")
                        .Where("status=@status", new { status = 1 })
                        .Select<ProxyNodesDTO>();
                    if (list == null) return default;
                    RedisHelper.Set(cache_key, list, 30 * 86400);
                }
            }
            _cached = list;
            return list;
        }
        public static void Refresh()
        {
            _ = List(true);
        }

    }

}
