using System;
using StellaOps.Feedser.Exporter.TrivyDb;
using StellaOps.Feedser.Storage.Mongo.Exporting;

namespace StellaOps.Feedser.Exporter.TrivyDb.Tests;

public sealed class TrivyDbExportPlannerTests
{
    [Fact]
    public void CreatePlan_ReturnsFullWhenStateMissing()
    {
        var planner = new TrivyDbExportPlanner();
        var manifest = new[] { new ExportFileRecord("path.json", 10, "sha256:a") };
        var plan = planner.CreatePlan(existingState: null, treeDigest: "sha256:abcd", manifest);

        Assert.Equal(TrivyDbExportMode.Full, plan.Mode);
        Assert.Equal("sha256:abcd", plan.TreeDigest);
        Assert.Null(plan.BaseExportId);
        Assert.Null(plan.BaseManifestDigest);
        Assert.True(plan.ResetBaseline);
        Assert.Equal(manifest, plan.Manifest);
    }

    [Fact]
    public void CreatePlan_ReturnsSkipWhenCursorMatches()
    {
        var planner = new TrivyDbExportPlanner();
        var existingManifest = new[] { new ExportFileRecord("path.json", 10, "sha256:a") };
        var state = new ExportStateRecord(
            Id: TrivyDbFeedExporter.ExporterId,
            BaseExportId: "20240810T000000Z",
            BaseDigest: "sha256:base",
            LastFullDigest: "sha256:base",
            LastDeltaDigest: null,
            ExportCursor: "sha256:unchanged",
            TargetRepository: "feedser/trivy",
            ExporterVersion: "1.0",
            UpdatedAt: DateTimeOffset.UtcNow,
            Files: existingManifest);

        var plan = planner.CreatePlan(state, "sha256:unchanged", existingManifest);

        Assert.Equal(TrivyDbExportMode.Skip, plan.Mode);
        Assert.Equal("sha256:unchanged", plan.TreeDigest);
        Assert.Equal("20240810T000000Z", plan.BaseExportId);
        Assert.Equal("sha256:base", plan.BaseManifestDigest);
        Assert.False(plan.ResetBaseline);
        Assert.Empty(plan.ChangedFiles);
        Assert.Empty(plan.RemovedPaths);
    }

    [Fact]
    public void CreatePlan_ReturnsFullWhenCursorDiffers()
    {
        var planner = new TrivyDbExportPlanner();
        var manifest = new[] { new ExportFileRecord("path.json", 10, "sha256:a") };
        var state = new ExportStateRecord(
            Id: TrivyDbFeedExporter.ExporterId,
            BaseExportId: "20240810T000000Z",
            BaseDigest: "sha256:base",
            LastFullDigest: "sha256:base",
            LastDeltaDigest: null,
            ExportCursor: "sha256:old",
            TargetRepository: "feedser/trivy",
            ExporterVersion: "1.0",
            UpdatedAt: DateTimeOffset.UtcNow,
            Files: manifest);

        var newManifest = new[] { new ExportFileRecord("path.json", 10, "sha256:b") };
        var plan = planner.CreatePlan(state, "sha256:new", newManifest);

        Assert.Equal(TrivyDbExportMode.Delta, plan.Mode);
        Assert.Equal("sha256:new", plan.TreeDigest);
        Assert.Equal("20240810T000000Z", plan.BaseExportId);
        Assert.Equal("sha256:base", plan.BaseManifestDigest);
        Assert.False(plan.ResetBaseline);
        Assert.Single(plan.ChangedFiles);

        var deltaState = state with { LastDeltaDigest = "sha256:delta" };
        var deltaPlan = planner.CreatePlan(deltaState, "sha256:newer", newManifest);

        Assert.Equal(TrivyDbExportMode.Full, deltaPlan.Mode);
        Assert.True(deltaPlan.ResetBaseline);
        Assert.Equal(deltaPlan.Manifest, deltaPlan.ChangedFiles);
    }
}
