using Knoks.Api.Client.Invoker;
using Knoks.Framework.Content;
//using Knoks.Test.Integrations.End2End;
using Microsoft.Extensions.CommandLineUtils;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Threading.Tasks;

namespace Knoks.Test.Integrations
{
    public class Program
    {
        private static ILoggerFactory LoggerFactory = new LoggerFactory().AddConsole().AddDebug();

        public static void Main1(string[] args)
        {
            var app = new CommandLineApplication();

            //app.Name = "ldi";

            app.OnExecute(() =>
            {
                Console.WriteLine("Hello World!");
                return 0;
            });

            //app.Command("bomber", command =>
            //{
            //    command.Description = "Run bomber for produce loan requsts.";
            //    command.HelpOption("-?|-h|--help");
            //    var countArgument = command.Argument("[count]", "Number of loan requests (1 by default).");
            //    var statusArgument = command.Argument("[status]", $"Target status (random by default for each loan requsst). {Environment.NewLine}\t-- supported statuses --{Environment.NewLine}\t" + string.Join($"{Environment.NewLine}\t", Bomber.SupportedStatuses.Select(s => $"({(int)s}) - {s}")));

            //    command.OnExecute(Go(command.Name, async () => 
            //    {
            //        var count = !string.IsNullOrWhiteSpace(countArgument.Value) ? int.Parse(countArgument.Value) : 100;
            //        var status = !string.IsNullOrWhiteSpace(statusArgument.Value) ? (LoanRequestStatusTypes?)int.Parse(statusArgument.Value) : null;

            //        Console.WriteLine($"Bomber running with arguments: count = {count}, status = {(status == null ? "null" : status.ToString())}");

            //        await new Bomber().MultiLoanRequest(count, status);
            //    }));
            //});

            app.Command("parse", command =>
            {
                command.Description = "Parse razor templates located on 'Templates' example folder.";
                command.HelpOption("-?|-h|--help");

                var categoryArgument = command.Argument("[category]", "category  ('Email' by default).");
                var groupArgument = command.Argument("[group]", "group ('welcome' by default).");
                var languageCodeArgument = command.Argument("[language code]", "language code ('en' by default).");

                command.OnExecute(Go(command.Name, () =>
                {
                    var category = categoryArgument.Value ?? "Email";
                    var name = groupArgument.Value ?? "welcome";
                    var languageCode = languageCodeArgument.Value ?? "en";

                    var generator = new ContentGenerator(LoggerFactory.CreateLogger<IContentGenerator>());

                    var contentResult = generator.GenerateContent(new ContentSettings
                    {
                        Category = category,
                        Group = name,
                        LanguageCode = languageCode,
                        Data = JObject.FromObject(new { Brand = new { BrandName = "Knoks" }, User = new { Username = "FanMix" } })
                    });

                    Console.WriteLine("## START TEMPLATE ###########################################################");
                    Console.WriteLine(contentResult.Content);
                    Console.WriteLine("## END TEMPLATE #############################################################");
                }));
            });

            app.HelpOption("-?|-h|--help");
            Environment.Exit(app.Execute(args));
        }

        #region Go methods
        private static Func<Task<int>> Go(string commandName, Func<Task> invoke)
        {
            return async () =>
            {
                var sw = Stopwatch.StartNew();
                try
                {
                    Console.WriteLine($"Start [{commandName}] command...");
                    await invoke();
                    Console.WriteLine($"End [{commandName}] command.");
                    return 0;
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Error on running {commandName}: {e.Message}");
                    return 1;
                }
                finally
                {
                    sw.Stop();
                    Console.WriteLine($"Time elapsed {sw.Elapsed}");
                }
            };
        }

        private static Func<int> Go(string commandName, Action invoke)
        {
            return () => { return Go(commandName, async () => { await Task.Run(invoke); })().Result; };
        }
        #endregion
    }
}
