using System.Diagnostics;
using Quadarax.Foundation.Core.Logging;
using Quadarax.Foundation.Core.QMonitor;
using Quadarax.Foundation.Core.QMonitor.Emit.TestStructures;

namespace Quadarax.Foundation.Core.QMonitor.Emit // Note: actual namespace depends on the project name.
{
    internal class Program
    {
        private static Random _rnd = new Random();

        static void Main(string[] args)
        {
            System.Console.WriteLine("qmonlib.emit * qmon random activity generator");
            System.Console.WriteLine("usage: qmonlib.emit <instance_name> <list_of_data>");
            System.Console.WriteLine("arguments:");
            System.Console.WriteLine("<instance_name> - mandatory. name of instance that generated data belongs");
            System.Console.WriteLine("<list_of_data> - optional. list of data categories to be generated (separated with semicolon). Available values are all (default),service,process,user");
            var instanceIdentifier = args.Length > 0 ? args[0] : "test";

            using (var qmonClient = new QMonClient(instanceIdentifier, QMonClientConfiuration.CreateDefault(), new ConsoleLogger()))
            {
                var ctx = new Context
                {
                    Client = qmonClient,
                    Status = new ServiceStatus(ServiceStatus.StatusEnum.Online, DateTime.Now),
                    AvailableUsers = CreateAvailableUsers()
                };
                var servicelist = "all";
                if (args.Length == 2)
                    servicelist = args[1].ToLower();
                Timer? tmStatus = null;
                Timer? tmProcesses = null;
                Timer? tmUsers = null;
                if (servicelist.Contains("all") || servicelist.Contains("service"))
                    tmStatus = new Timer(OnServiceStatusTimer, ctx, TimeSpan.Zero, TimeSpan.FromSeconds(5));
                if (servicelist.Contains("all") || servicelist.Contains("process"))
                    tmProcesses = new Timer(OnProcessesTimer, ctx, TimeSpan.Zero, TimeSpan.FromSeconds(2));
                if (servicelist.Contains("all") || servicelist.Contains("user"))
                    tmUsers = new Timer(OnUsersTimer, ctx, TimeSpan.Zero, TimeSpan.FromSeconds(2));


                System.Console.WriteLine("Press any key to stop...");
                System.Console.ReadKey();
                tmStatus?.Dispose();
                tmProcesses?.Dispose();
                tmUsers?.Dispose();
                System.Console.WriteLine("Stopped.");
            }
        }

        private static void OnUsersTimer(object? state)
        {
            System.Console.WriteLine("* OnUsersTimer");
            if (state == null) return;
            var ctx = (Context)state;

            foreach (var user in ctx.AvailableUsers)
            {
                var randomBool = _rnd.Next(2) == 1;
                if (randomBool)
                    ctx.Client.Notify(user);
            }
        }

        private static void OnProcessesTimer(object? state)
        {
            System.Console.WriteLine("* OnProcessesTimer");
            if (state == null) return;
            var ctx = (Context)state;

            var processes = Process.GetProcesses();
            foreach (var process in processes)
            {
                if (process.Id == 0 || process.Id == 4) continue; // skip system idle process (it's not real process

                var ntfProcess = new ProcessItem()
                {
                    Id = process.Id,
                    Name = process.ProcessName,
                    Status = process.Responding ? "Running" : "Not Responding",
                    Path = process.ProcessName + ".exe"
                };
                ctx.Client.Notify(ntfProcess);
            }
        }

        private static void OnServiceStatusTimer(object? state)
        {
            System.Console.WriteLine("* OnServiceStatusTimer");
            if (state == null) return;
            var ctx = (Context)state;
            var randomBool = _rnd.Next(2) == 1;
            if (randomBool)
            {
                if (ctx.Status.Status == ServiceStatus.StatusEnum.Offline)
                {
                    ctx.Status.Status = ServiceStatus.StatusEnum.Online;
                    ctx.Status.Started = DateTime.Now;
                }
            }
            else
            {
                ctx.Status.Status = ServiceStatus.StatusEnum.Offline;
            }
            System.Console.WriteLine($"# OnServiceStatusTimer-> status: {ctx.Status.Status}");
            ctx.Client.Notify(ctx.Status);
        }

        public static LoggedUser[] CreateAvailableUsers()
        {
            return new[]
            {
                new LoggedUser() { Id = 1, FirstName = "Karel", LastName = "Gott", Login = "karel.gott" },
                new LoggedUser() { Id = 2, FirstName = "Vasil", LastName = "Bilak", Login = "vasko32" },
                new LoggedUser() { Id = 3, FirstName = "Alois", LastName = "Šoule", Login = "alois.soule" },
                new LoggedUser() { Id = 4, FirstName = "Květoslav", LastName = "Pytlík", Login = "kvetak55" },
                new LoggedUser() { Id = 5, FirstName = "Jindra", LastName = "Kedlub", Login = "kedlubna" },
                new LoggedUser() { Id = 6, FirstName = "Vlasta", LastName = "Henych", Login = "retard" },
                new LoggedUser() { Id = 7, FirstName = "Petr", LastName = "Volavka", Login = "petro.vol" },
                new LoggedUser() { Id = 8, FirstName = "Jan", LastName = "Prášil", Login = "jenda45" },
                new LoggedUser() { Id = 9, FirstName = "Donald", LastName = "Paprika", Login = "spicy.leco" },
                new LoggedUser() { Id = 10, FirstName = "Mustafa", LastName = "Novák", Login = "vlastenec48" },
            };
        }

        public class Context
        {
            public QMonClient Client { get; set; }

            public ServiceStatus Status { get; set; }

            public LoggedUser[] AvailableUsers { get; set; }
        }



    }
}