using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using SharpRSS.API.Models;
using ToolQit;
using ToolQit.Logging;

namespace SharpRSS.API.Data
{
    internal sealed class DbAccess : DbContext
    {
        public DbAccess(IConfiguration configuration)
        {
            _log = LogManager.CreateLogger(typeof(DbAccess));
            _log.Debug("Initializing new context...");
            _configuration = configuration;
            _dbServer = _configuration["DataBase:Server"] ?? "Unknown";
            ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
            ChangeTracker.LazyLoadingEnabled = false;
            Database.EnsureCreated();
        }
        
        public DbSet<DbUser> Users { get; set; }
        public DbSet<DbGroup> Groups { get; set; }
        public DbSet<DbSession> Sessions { get; set; }

        private readonly IConfiguration _configuration;
        private readonly ILog _log;
        private readonly string _dbServer;

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            string connection = _configuration["DataBase:Connection"] ?? throw new ArgumentNullException(nameof(_configuration), "No connection string in appsettings!");
            switch (_dbServer)
            {
                case "MariaDB":
                    var dbSrvVersion = ServerVersion.AutoDetect(connection);
                    _log.Information("Server {SrvType} detected, version: {SrvVersion}", dbSrvVersion.Type.ToString(), dbSrvVersion.Version);
                    optionsBuilder.UseMySql(connection, dbSrvVersion);
                    break;
                default: // TODO: Add more database support.
                    _log.Warning("No valid db server: {Server}\nSupported db servers: 'MariaDB'", _dbServer);
                    throw new Exception("Database server not specified!");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            switch (_dbServer)
            {
                case "MariaDB":
                    modelBuilder.UseCollation("utf8mb4_unicode_520_ci");
                    break;
                default:
                    break;
            }
            modelBuilder.Entity<DbUser>().ToTable("srss_users").HasKey(dbu => dbu.Uid);
            modelBuilder.Entity<DbGroup>().ToTable("srss_groups").HasKey(dbg => dbg.Gid);
            modelBuilder.Entity<DbSession>().ToTable("srss_sessions").HasKey(dbs => dbs.Sid);
            base.OnModelCreating(modelBuilder);
        }
    }
}