// <copyright file="SupplementaryIndexChecker.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace Jellyfin.Server.Implementations.Database;

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Npgsql;

/// <summary>
/// Ensures supplementary performance indexes exist on database startup.
/// </summary>
public class SupplementaryIndexChecker
{
    private readonly ILogger<SupplementaryIndexChecker> _logger;
    private readonly DbContext _context;

    /// <summary>
    /// Initializes a new instance of the <see cref="SupplementaryIndexChecker"/> class.
    /// </summary>
    /// <param name="logger">The logger.</param>
    /// <param name="context">The database context.</param>
    public SupplementaryIndexChecker(ILogger<SupplementaryIndexChecker> logger, DbContext context)
    {
        _logger = logger;
        _context = context;
    }

    /// <summary>
    /// Checks if supplementary indexes exist and logs warnings if they don't.
    /// </summary>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>True if all indexes exist, false otherwise.</returns>
    public async Task<bool> CheckSupplementaryIndexesAsync(CancellationToken cancellationToken = default)
    {
        try
        {
            var connection = _context.Database.GetDbConnection();
            await connection.OpenAsync(cancellationToken).ConfigureAwait(false);

            var checkQuery = @"
                SELECT COUNT(*) 
                FROM pg_indexes 
                WHERE indexname IN (
                    'idx_baseitems_type_isvirtualitem_topparentid',
                    'idx_baseitems_topparentid_isfolder',
                    'idx_baseitems_datecreated_filtered',
                    'idx_itemvaluesmap_itemvalueid_itemid',
                    'idx_activitylogs_userid_datecreated'
                )";

            await using var command = connection.CreateCommand();
            command.CommandText = checkQuery;
            var result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);
            var indexCount = Convert.ToInt32(result);

            if (indexCount < 5)
            {
                _logger.LogWarning(
                    "Only {IndexCount}/5 supplementary performance indexes found. " +
                    "Run 'sql/schema_init/10_create_supplementary_indexes.sql' to add missing indexes for better performance.",
                    indexCount);
                return false;
            }

            _logger.LogInformation("All supplementary performance indexes are present ({IndexCount}/5).", indexCount);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to check supplementary indexes");
            return false;
        }
    }
}
