﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ElasticTools.Client;
using Newtonsoft.Json;

namespace ElasticTools.Console
{
    class Program
    {
        private static List<MonitorHandle> monitors = new List<MonitorHandle>();
        private static ConsoleLogger _logger;
        static void Main(string[] args)
        {
            _logger = new ConsoleLogger();

            var connectionPool = new List<string>() { "http://ess-01:9200" };
            var settings = new ClientSettings(connectionPool,"event_log");
            var client = new Client.Client(settings);
            GetStatusCode(client);

            var indexOperations = new IndexOperations(client);
            
            //Reindex(indexOperations);
            Monitor(indexOperations);

            System.Console.ReadLine();
            //stop the monitors
            monitors.ForEach((m)=> m.Stop());
            System.Console.ReadLine();
        }

        private static async void GetStatusCode(Client.Client client)
        {
            var result = await client.GetStatusCode().ConfigureAwait(false);
            _logger.LogDiagnostic($"Status code {result.Value}");
        }

        public static async void Reindex(IndexOperations indexOperations)
        {
            var result = await indexOperations.ReindexAsync("event_log", "getEntry");
            _logger.LogMessage("Complete");
        }

        public static async void Monitor(IndexOperations indexOperations)
        {
            var typeMonitors = new[] {"getEntry","searchEntry","errorEntry","indexEntry","logEntry"};
            foreach (var typeMonitor in typeMonitors)
            {
                var monitorHandle = indexOperations.GetMonitorHandle("event_log", typeMonitor, "_timestamp");
                monitorHandle.Action = PrintAction(typeMonitor);
                monitors.Add(monitorHandle);

            }
            var tasks = new List<Task>();
            monitors.ForEach((handle => tasks.Add(handle.Run())));
            await Task.WhenAll(tasks).ConfigureAwait(false);

            _logger.LogMessage("Complete");
        }

        public static int totalCount = 0;
        public static Action<IEnumerable<IDocumentUpdate>> PrintAction(string monitorName)
        {
            return (a) =>
            {
                var count = a.Count();
                if (count > 0)
                {
                    //we can get the source now from this variable
                    string source = a.First().Source.ToString();
                    var entry = JsonConvert.DeserializeObject<GetEntry>(source);
                    totalCount += count;
                    System.Console.WriteLine($"{monitorName}: {totalCount}");
                }
            };
        }
    }

    public class GetEntry
    {
        [JsonProperty("requestMilliseconds")]
        public long RequestMilliseconds { get; set; }

        [JsonProperty("found")]
        public bool Found { get; set; }

        [JsonProperty("docId")]
        public string DocId { get; set; }

        [JsonProperty("requestUrl")]
        public string RequestUrl { get; set; }

        [JsonProperty("index")]
        public string  Index { get; set; }

        [JsonProperty("type")]
        public string  Type { get; set; }

        [JsonProperty("applicationName")]
        public string ApplicationName { get; set; }

        [JsonProperty("machineName")]
        public string MachineName { get; set; }

        [JsonProperty("timestamp")]
        public long Timestamp { get; set; }

    }
}
