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

namespace Emby.Server.Implementations.Tests.AppBase;

using System;
using System.IO;
using System.Text.Json;
using Emby.Server.Implementations.AppBase;
using Jellyfin.Database.Implementations.DbConfiguration;
using Jellyfin.Extensions.Json;
using Xunit;

/// <summary>
/// Tests for the ConfigurationHelper JSON loading functionality.
/// </summary>
public class ConfigurationHelperTests
{
    [Fact]
    public void GetJsonConfiguration_ValidJsonFile_DeserializesCorrectly()
    {
        // Arrange
        var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
        var jsonPath = Path.Combine(tempDir, "test-config.json");

        var testConfig = new DatabaseConfigurationOptions
        {
            DatabaseType = "Jellyfin-PostgreSQL",
            LockingBehavior = DatabaseLockingBehaviorTypes.NoLock
        };

        Directory.CreateDirectory(tempDir);
        var json = JsonSerializer.Serialize(testConfig, JsonDefaults.Options);
        File.WriteAllText(jsonPath, json);

        try
        {
            // Act
            var result = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);

            // Assert
            Assert.NotNull(result);
            Assert.Equal("Jellyfin-PostgreSQL", result.DatabaseType);
            Assert.Equal(DatabaseLockingBehaviorTypes.NoLock, result.LockingBehavior);
        }
        finally
        {
            // Cleanup
            if (Directory.Exists(tempDir))
            {
                Directory.Delete(tempDir, recursive: true);
            }
        }
    }

    [Fact]
    public void GetJsonConfiguration_MissingFile_CreatesDefaultAndReturnsIt()
    {
        // Arrange
        var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
        var jsonPath = Path.Combine(tempDir, "test-config.json");

        try
        {
            // Act
            var result = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);

            // Assert
            Assert.NotNull(result);
            Assert.True(File.Exists(jsonPath), "JSON file should be created");

            // Verify the file is valid JSON
            var fileContent = File.ReadAllText(jsonPath);
            var deserialized = JsonSerializer.Deserialize<DatabaseConfigurationOptions>(fileContent, JsonDefaults.Options);
            Assert.NotNull(deserialized);
        }
        finally
        {
            // Cleanup
            if (Directory.Exists(tempDir))
            {
                Directory.Delete(tempDir, recursive: true);
            }
        }
    }

    [Fact]
    public void GetJsonConfiguration_WithCustomProviderOptions_PreservesSettings()
    {
        // Arrange
        var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
        var jsonPath = Path.Combine(tempDir, "test-config.json");

        var testConfig = new DatabaseConfigurationOptions
        {
            DatabaseType = "Jellyfin-PostgreSQL",
            LockingBehavior = DatabaseLockingBehaviorTypes.Pessimistic,
            CustomProviderOptions = new CustomDatabaseOptions
            {
                PluginName = "Jellyfin-PostgreSQL",
                PluginAssembly = "Jellyfin.Database.Providers.Postgres",
                ConnectionString = "Host=localhost;Port=5432;Database=jellyfin;Username=jellyfin;Password=secret"
            }
        };

        Directory.CreateDirectory(tempDir);
        var json = JsonSerializer.Serialize(testConfig, JsonDefaults.Options);
        File.WriteAllText(jsonPath, json);

        try
        {
            // Act
            var result = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);

            // Assert
            Assert.NotNull(result);
            Assert.Equal("Jellyfin-PostgreSQL", result.DatabaseType);
            Assert.Equal(DatabaseLockingBehaviorTypes.Pessimistic, result.LockingBehavior);
            Assert.NotNull(result.CustomProviderOptions);
            Assert.Equal("Jellyfin-PostgreSQL", result.CustomProviderOptions.PluginName);
            Assert.Equal("Host=localhost;Port=5432;Database=jellyfin;Username=jellyfin;Password=secret", 
                result.CustomProviderOptions.ConnectionString);
        }
        finally
        {
            // Cleanup
            if (Directory.Exists(tempDir))
            {
                Directory.Delete(tempDir, recursive: true);
            }
        }
    }

    [Fact]
    public void GetJsonConfiguration_InvalidJson_CreatesDefault()
    {
        // Arrange
        var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
        var jsonPath = Path.Combine(tempDir, "test-config.json");

        Directory.CreateDirectory(tempDir);
        File.WriteAllText(jsonPath, "{ invalid json");

        try
        {
            // Act
            var result = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);

            // Assert - should get default instance on invalid JSON
            Assert.NotNull(result);
        }
        finally
        {
            // Cleanup
            if (Directory.Exists(tempDir))
            {
                Directory.Delete(tempDir, recursive: true);
            }
        }
    }

    [Fact]
    public void GetJsonConfiguration_RoundTrip_PreservesData()
    {
        // Arrange
        var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
        var jsonPath = Path.Combine(tempDir, "test-config.json");

        var originalConfig = new DatabaseConfigurationOptions
        {
            DatabaseType = "Jellyfin-PostgreSQL",
            LockingBehavior = DatabaseLockingBehaviorTypes.Optimistic
        };

        Directory.CreateDirectory(tempDir);

        try
        {
            // Act - First load should create the file
            var result1 = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);

            // Modify and verify round-trip
            var json = JsonSerializer.Serialize(originalConfig, JsonDefaults.Options);
            File.WriteAllText(jsonPath, json);

            var result2 = ConfigurationHelper.GetJsonConfiguration<DatabaseConfigurationOptions>(jsonPath);

            // Assert
            Assert.NotNull(result2);
            Assert.Equal("Jellyfin-PostgreSQL", result2.DatabaseType);
            Assert.Equal(DatabaseLockingBehaviorTypes.Optimistic, result2.LockingBehavior);
        }
        finally
        {
            // Cleanup
            if (Directory.Exists(tempDir))
            {
                Directory.Delete(tempDir, recursive: true);
            }
        }
    }
}
