using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Knoks.Core.Data.Dao;
using Knoks.Core.Entities.Settings;
using Knoks.Core.Logic.Managers;
using Knoks.Framework.DataAccess;
using Knoks.Framework.Extentions;
using Knoks.Framework.Services;
using Knoks.TokenContractTracking;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace TokenContractTrackerConsoleTestApp
{
    class Program
    {
        private static TokenContractTracker _tokenContractTracker;
        private static ILoggerFactory _loggerFactory = new LoggerFactory();

        private static ILogger _logger = _loggerFactory.CreateLogger<Program>();

        static async Task Main(string[] args)
        {
            try
            {
                var configuration = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                    .Build();

                var loggingSection = configuration.GetSection("Logging");
                _loggerFactory.AddConsole(loggingSection);
                _loggerFactory.AddDebug();

                var procExecutor = new ProcExecutor(configuration.Load<Dictionary<string, string>>("DbConnections"), _loggerFactory.CreateLogger<ProcExecutor>());

                var userDao = new UserDao(_loggerFactory.CreateLogger<UserDao>(), procExecutor);
                var accountDao = new AccountDao(_loggerFactory.CreateLogger<AccountDao>(), procExecutor);
                var userManager = new UserManager(_loggerFactory.CreateLogger<UserManager>(), userDao, null, null, null, null, accountDao, null, configuration.Load<AccountTransactionsSettings>());
                await userManager.Initialize();

                var accountTransactionManager = new AccountTransactionManager(userManager,
                    new AccountTransactionDao(_loggerFactory.CreateLogger<AccountTransactionDao>(), procExecutor));

                var contractSettings = configuration.Load<TokenContractTrackerSettings>();
                var ethSettings = configuration.Load<EthereumConnectionSettings>();
                _tokenContractTracker = new TokenContractTracker(contractSettings, ethSettings, _loggerFactory.CreateLogger<TokenContractTracker>(), accountTransactionManager, userManager,
                    accountDao);

                Console.CancelKeyPress += Console_CancelKeyPress;

                await _tokenContractTracker.Init();

                _tokenContractTracker.Start();

                _logger.LogInformation($"Signals tracker started. Press Ctrl + C to stop{Environment.NewLine}");
                await _tokenContractTracker.WaitForCompletion();
            }
            catch (Exception exxot)
            {
                _logger.LogError(exxot, "Pabam! We failed. Press any key to close");
            }
            finally
            {
                _tokenContractTracker.Dispose();
            }

            _logger.LogInformation("Tender Events Dispatcher exited.");

            Console.WriteLine($"{Environment.NewLine}Press Enter to exit{Environment.NewLine}");
            Console.ReadLine();
        }

        private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            e.Cancel = true;
            _tokenContractTracker.Stop();
        }
    }
}
