using Elasticsearch.Net;
using Nest;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace CsvCount_ES
{

    public sealed class ESClientConfigureManager
    {
        public static List<Uri> Uris { get; private set; }

        public static String DefaultIndex { get; private set; }

        /// <summary>
        /// ES连接设置
        /// </summary>
        public static ConnectionSettings ConnectSetting { get; private set; }

        private const String ConnectionStringIndex = "ESDatabase";

        private const String HostIndex = "host";
        private const String PortIndex = "port";
        private const String DefaultIndexIndex = "defaultIndex";
        private const String RequestTimeout = "requesttimeout";

        static ESClientConfigureManager()
        {
             
                String connectionString = ConfigurationManager.ConnectionStrings[ConnectionStringIndex].ConnectionString;
                String[] namedValues = connectionString.Split(';');
                Dictionary<String, String> nvPair = new Dictionary<String, String>();
                foreach (String nv in namedValues)
                {
                    String[] pair = nv.Split('=');
                    nvPair[pair[0]] = pair[1];
                }

                String _url = GetValueByName(nvPair, HostIndex, "tank.palaspom.com");
                String _port = GetValueByName(nvPair, PortIndex, "19235");


                //支持多Uri模式，要求多个链接使用 | 分隔，在分隔后数量相同的情况下按照顺序一一对应，如果其中一方仅有一个则使用它对应对方所有部分
                string[] urls = _url.Split('|');
                string[] ports = _port.Split('|');

                if (urls == null || ports == null || urls.Length < 1 || ports.Length < 1)
                    throw new Exception("Unable get the elasticsearch config pool setting.");

                Uris = new List<Uri>();

                if (urls.Length == ports.Length)
                {
                    for (int i = 0; i < urls.Length; i++)
                    {
                        String formattedUrl = Regex.IsMatch(urls[i], @"://") ? urls[i] : String.Format("http://{0}", urls[i]);
                        Uris.Add(new Uri(String.Format("{0}:{1}", formattedUrl, ports[i])));
                    }
                }
                else if (urls.Length > 1 && ports.Length == 1)
                {
                    for (int i = 0; i < urls.Length; i++)
                    {
                        String formattedUrl = Regex.IsMatch(urls[i], @"://") ? urls[i] : String.Format("http://{0}", urls[i]);
                        Uris.Add(new Uri(String.Format("{0}:{1}", formattedUrl, ports[0])));
                    }
                }
                else if (urls.Length == 1 && ports.Length > 1)
                {
                    String formattedUrl = Regex.IsMatch(urls[0], @"://") ? urls[0] : String.Format("http://{0}", urls[0]);
                    for (int i = 0; i < ports.Length; i++)
                    {
                        Uris.Add(new Uri(String.Format("{0}:{1}", formattedUrl, ports[i])));
                    }
                }
                else
                {
                    throw new Exception("The elasticsearch config pool setting is error.");
                }

                var pool = new StaticConnectionPool(Uris);

                String index = GetValueByName(nvPair, DefaultIndexIndex, "palas");
                DefaultIndex = index;

                int _requesttimeout = int.Parse(GetValueByName(nvPair, RequestTimeout, "100000"));


                ConnectSetting = new ConnectionSettings(pool).BasicAuthentication("carey", "jfyhdcm").DefaultIndex(index).DisableDirectStreaming().RequestTimeout(TimeSpan.FromMilliseconds(_requesttimeout)).ConnectionLimit(10000).DeadTimeout(TimeSpan.FromMilliseconds(_requesttimeout)).PingTimeout(TimeSpan.FromMilliseconds(_requesttimeout)).MaxRetryTimeout(TimeSpan.FromMilliseconds(_requesttimeout));

         

        }

        private static String GetValueByName(Dictionary<String, String> nvPair, String name, String defaultValue)
        {
            String value = null;
            if (nvPair.TryGetValue(name, out value))
            {
                return value;
            }
            return defaultValue;
        }
    }
}
