using GeViScopeBridge.Services;
using GeViScopeBridge.SDK;
using Serilog;
using Microsoft.Extensions.Configuration;

namespace GeViScopeBridge
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            // Configure Serilog
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Console()
                .WriteTo.File("logs/sdk-bridge-.log", rollingInterval: RollingInterval.Day)
                .CreateLogger();

            try
            {
                Log.Information("Starting GeViScope SDK Bridge (gRPC Server)");

                // Load configuration
                var configuration = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", optional: false)
                    .AddEnvironmentVariables()
                    .Build();

                // Get GeViServer connection settings
                string geviServerHost = configuration["GeViServer:Host"] ?? "localhost";
                string geviServerUsername = configuration["GeViServer:Username"] ?? "sysadmin";
                string geviServerPassword = configuration["GeViServer:Password"] ?? "masterkey";
                int grpcPort = int.Parse(configuration["GrpcServer:Port"] ?? "50051");

                Log.Information("Configuration loaded: GeViServer={Host}, gRPC Port={Port}",
                    geviServerHost, grpcPort);

                // Create SDK wrapper
                var dbWrapper = new GeViDatabaseWrapper(
                    geviServerHost,
                    geviServerUsername,
                    geviServerPassword,
                    Log.Logger);

                // Connect to GeViServer
                Log.Information("Connecting to GeViServer...");
                bool connected = await dbWrapper.ConnectAsync();

                if (!connected)
                {
                    Log.Fatal("Failed to connect to GeViServer. Exiting.");
                    return;
                }

                Log.Information("Successfully connected to GeViServer");

                // Create SDK handlers
                var stateQueryHandler = new StateQueryHandler(dbWrapper, Log.Logger);
                var actionDispatcher = new ActionDispatcher(dbWrapper, Log.Logger);

                // Build gRPC server
                var builder = WebApplication.CreateBuilder(args);

                // Add gRPC services
                builder.Services.AddGrpc();

                // Add singletons
                builder.Services.AddSingleton(dbWrapper);
                builder.Services.AddSingleton(stateQueryHandler);
                builder.Services.AddSingleton(actionDispatcher);
                builder.Services.AddSingleton(Log.Logger);

                // Configure Kestrel for gRPC
                builder.WebHost.ConfigureKestrel(options =>
                {
                    options.ListenAnyIP(grpcPort, listenOptions =>
                    {
                        listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
                    });
                });

                var app = builder.Build();

                // Map gRPC services
                app.MapGrpcService<CameraServiceImplementation>();
                app.MapGrpcService<MonitorServiceImplementation>();
                app.MapGrpcService<CrossSwitchServiceImplementation>();

                // Add health check endpoint
                app.MapGet("/", () => "GeViScope SDK Bridge (gRPC) - Use a gRPC client to connect");

                Log.Information("gRPC server starting on port {Port}", grpcPort);
                Log.Information("Services registered: CameraService, MonitorService, CrossSwitchService");

                await app.RunAsync();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Application terminated unexpectedly");
            }
            finally
            {
                Log.Information("Shutting down GeViScope SDK Bridge");
                Log.CloseAndFlush();
            }
        }
    }
}
