using Serilog;
using Serilog.Enrichers.Sensitive;
using Serilog.Events;
using Serilog.Sinks.MSSqlServer;

namespace Indotalent.Infrastructure.Logging.Serilog;

public static class SerilogBuilder
{
    public static void AddSerilogBuilder(this WebApplicationBuilder builder)
    {
        var settings = builder.Configuration.GetSection("LoggerSettings").Get<LoggerSettingsModel>();

        var loggerConfiguration = new LoggerConfiguration()
            .ReadFrom.Configuration(builder.Configuration)
            .Enrich.FromLogContext()
            .Enrich.WithMachineName()
            .Enrich.WithThreadId()
            .Enrich.WithSensitiveDataMasking(options =>
            {
                options.MaskValue = "***MASKED***";

                options.MaskProperties.Add(MaskProperty.WithDefaults("Password"));
                options.MaskProperties.Add(MaskProperty.WithDefaults("Secret"));
                options.MaskProperties.Add(MaskProperty.WithDefaults("Token"));
                options.MaskProperties.Add(MaskProperty.WithDefaults("ApiKey"));
                options.MaskProperties.Add(MaskProperty.WithDefaults("ConfirmPassword"));

            })
            .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}");

        if (settings?.File?.IsUsed == true)
        {
            var interval = settings.File.RollingInterval.ToLower() switch
            {
                "hour" => RollingInterval.Hour,
                "month" => RollingInterval.Month,
                _ => RollingInterval.Day
            };

            loggerConfiguration.WriteTo.File(
                path: settings.File.Path,
                rollingInterval: interval,
                restrictedToMinimumLevel: LogEventLevel.Error,
                outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}");
        }

        if (settings?.Database?.IsUsed == true)
        {
            var columnOptions = new ColumnOptions();
            columnOptions.Store.Add(StandardColumn.LogEvent);
            columnOptions.LogEvent.ColumnName = "LogEvent";
            var connectionString = builder.Configuration.GetSection("DatabaseSettings:MsSQL:ConnectionString").Value;

            if (!string.IsNullOrEmpty(connectionString))
            {
                loggerConfiguration.WriteTo.MSSqlServer(
                    connectionString: connectionString,
                    sinkOptions: new MSSqlServerSinkOptions
                    {
                        TableName = settings.Database.TableName,
                        AutoCreateSqlTable = settings.Database.AutoCreateSqlTable
                    },
                    columnOptions: columnOptions,
                    restrictedToMinimumLevel: LogEventLevel.Error);
            }
        }

        if (settings?.Seq?.IsUsed == true && !string.IsNullOrEmpty(settings.Seq.ServerUrl))
        {
            // Send logs to the Seq server (Self-hosted dashboard by Datalust [https://datalust.co/])
            loggerConfiguration.WriteTo.Seq(
                serverUrl: settings.Seq.ServerUrl,
                restrictedToMinimumLevel: LogEventLevel.Information
            );
        }

        Log.Logger = loggerConfiguration.CreateLogger();
        builder.Host.UseSerilog();
    }
}
