using EVCB_OCPP.Domain;
using EVCB_OCPP.WSServer.Message;
using EVCB_OCPP.WSServer.Service;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using NLog;
using NLog.Web;
using NLog.Extensions.Logging;
using System.IO;
using System.Data.Common;
using Microsoft.Data.SqlClient;

namespace EVCB_OCPP.WSServer
{
   
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("====================================================================================================");
            Console.WriteLine("====================================================================================================");
            Console.WriteLine("==                                                                                                ==");
            Console.WriteLine("==       ------------               -----------      -------------         -------------          ==");
            Console.WriteLine("==    ---            ---       ----                  ----------------      ----------------       ==");
            Console.WriteLine("==    ---            ---     ----                    ----            ---   ----            ---    ==");
            Console.WriteLine("==    ---            ---    ----                     ----            ---   ----            ---    ==");
            Console.WriteLine("==    ---            ---    ----                     ---- -------------    ---- -------------     ==");
            Console.WriteLine("==    ---            ---    ----                     ---- -----------      ---- -----------       ==");
            Console.WriteLine("==    ---            ---      ----                   ----                  ----                   ==");
            Console.WriteLine("==    ---            ---        ----                 ----                  ----                   ==");
            Console.WriteLine("==       -----------                -----------      ----                  ----                   ==");
            Console.WriteLine("==                                                                                                ==");
            Console.WriteLine("====================================================================================================");
            Console.WriteLine("====================================================================================================");


            IHost host = Host.CreateDefaultBuilder(args)
                .ConfigureLogging((context, builder) => { 
                    builder.ClearProviders();
                    NLog.LogManager.Configuration = new NLogLoggingConfiguration(context.Configuration.GetSection("NLog"));
                })
                .UseNLog()
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddPooledDbContextFactory<MainDBContext>((options) => {
                        var cString = hostContext.Configuration.GetConnectionString("MainDBContext");
                        //var connection = new SqlConnection(cString);
                        //connection.Open();
                        //var com = new SqlCommand("SET ARITHABORT ON", connection);
                        //com.ExecuteNonQuery();
                        //com.Dispose();
                        //connection.Close();
                        //options.UseSqlServer(connection, dbOptions =>
                        //{
                        //    dbOptions.CommandTimeout(180);
                        //});
                        //options.LogTo(Console.WriteLine).EnableDetailedErrors();
                        options.UseSqlServer(cString, dbOptions =>
                        {
                            dbOptions.EnableRetryOnFailure(int.MaxValue);
                            dbOptions.CommandTimeout(int.MaxValue);
                        });
                    });
                    services.AddPooledDbContextFactory<MeterValueDBContext>((options) => {
                        var cString = hostContext.Configuration.GetConnectionString("MeterValueDBContext");
                        options.UseSqlServer(cString, dbOptions => {
                            dbOptions.EnableRetryOnFailure(int.MaxValue);
                            dbOptions.CommandTimeout(int.MaxValue);
                        });
                    });
                    services.AddPooledDbContextFactory<ConnectionLogDBContext>((options) => {
                        var cString = hostContext.Configuration.GetConnectionString("ConnectionLogDBContext");
                        options.UseSqlServer(cString, dbOptions => {
                            dbOptions.EnableRetryOnFailure(int.MaxValue);
                            dbOptions.CommandTimeout(int.MaxValue);
                        });
                    });

                    services.AddSingleton<ProfileHandler>();

                    services.AddScoped<OuterBusinessService>();
                    services.AddScoped<LocalBusinessService>();
                    services.AddScoped<CPOOuterResponse>();
                    services.AddSingleton<BusinessServiceFactory>();

                    //services.AddHostedService<ProtalServer>();

                    services.AddProtalServer();
                })
                .Build();

            host.Run();

            //ProtalServer s = new ProtalServer();
            //Console.WriteLine("Starting Server...");
            //s.Start();

            //Console.Read();
        }

        public static object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            DateTime? timevalue = null;
            if (reader.Value != null)
            {
                DateTime date = ((DateTime)reader.Value).ToLocalTime();
                timevalue = new DateTime(date.Year, date.Month, date.Day, date.TimeOfDay.Hours, date.TimeOfDay.Minutes, date.TimeOfDay.Seconds, 000);
            }
            return timevalue;
        }
    }
}
