using Microsoft.Extensions.Options;
using ZB.MOM.WW.GalaxyRepository;

namespace ZB.MOM.WW.GalaxyRepository.Tests;

/// <summary>
///     Round-trip tests for the real <see cref="GalaxyHierarchySnapshotStore"/> over a temp
///     file path: save then load, no-op when persistence is disabled, and clean disposal.
/// </summary>
public sealed class GalaxyHierarchySnapshotStoreTests : IDisposable
{
    private readonly string _path = Path.Combine(
        Path.GetTempPath(),
        $"galaxyrepo-snap-{Guid.NewGuid():N}.json");

    public void Dispose()
    {
        if (File.Exists(_path))
        {
            File.Delete(_path);
        }
    }

    private static GalaxyHierarchySnapshot SampleSnapshot() => new(
        LastDeployTime: new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero),
        SavedAt: new DateTimeOffset(2026, 1, 1, 12, 0, 0, TimeSpan.Zero),
        Hierarchy:
        [
            new GalaxyHierarchyRow { GobjectId = 1, TagName = "Area1", IsArea = true },
            new GalaxyHierarchyRow { GobjectId = 2, TagName = "Pump01", ParentGobjectId = 1 },
        ],
        Attributes:
        [
            new GalaxyAttributeRow { GobjectId = 2, AttributeName = "PV", FullTagReference = "Pump01.PV", IsHistorized = true },
        ]);

    [Fact]
    public async Task SaveThenLoad_RoundTripsTheSnapshot()
    {
        using GalaxyHierarchySnapshotStore store = new(
            Options.Create(new GalaxyRepositoryOptions { PersistSnapshot = true, SnapshotCachePath = _path }));

        await store.SaveAsync(SampleSnapshot(), CancellationToken.None);
        GalaxyHierarchySnapshot? loaded = await store.TryLoadAsync(CancellationToken.None);

        Assert.NotNull(loaded);
        Assert.Equal(2, loaded!.Hierarchy.Count);
        Assert.Single(loaded.Attributes);
        Assert.Equal("Pump01.PV", loaded.Attributes[0].FullTagReference);
        Assert.True(loaded.Attributes[0].IsHistorized);
        Assert.Equal(SampleSnapshot().LastDeployTime, loaded.LastDeployTime);
    }

    [Fact]
    public async Task SaveAndLoad_AreNoOps_WhenPersistenceDisabled()
    {
        using GalaxyHierarchySnapshotStore store = new(
            Options.Create(new GalaxyRepositoryOptions { PersistSnapshot = false, SnapshotCachePath = _path }));

        await store.SaveAsync(SampleSnapshot(), CancellationToken.None);

        Assert.False(File.Exists(_path));
        Assert.Null(await store.TryLoadAsync(CancellationToken.None));
    }

    [Fact]
    public async Task TryLoad_ReturnsNull_WhenNoFileExists()
    {
        using GalaxyHierarchySnapshotStore store = new(
            Options.Create(new GalaxyRepositoryOptions { PersistSnapshot = true, SnapshotCachePath = _path }));

        Assert.Null(await store.TryLoadAsync(CancellationToken.None));
    }

    [Fact]
    public async Task TryLoad_ReturnsNull_WhenFileIsNotValidJson()
    {
        await File.WriteAllTextAsync(_path, "{ this is not valid json");
        using GalaxyHierarchySnapshotStore store = new(
            Options.Create(new GalaxyRepositoryOptions { PersistSnapshot = true, SnapshotCachePath = _path }));

        Assert.Null(await store.TryLoadAsync(CancellationToken.None));
    }
}
