namespace Kompas.Mcp.Tests;

/// <summary>Публикуемые навыки должны быть самодостаточны: без ссылок на внутренности репозитория.</summary>
[Trait("Category", "Unit")]
public sealed class PluginSkillsTests
{
    private static string SkillsRoot => Path.Combine(TestPaths.RepoRoot(), "plugin", "skills");

    public static TheoryData<string> SkillFiles()
    {
        var data = new TheoryData<string>();
        foreach (var file in Directory.GetFiles(SkillsRoot, "*.md", SearchOption.AllDirectories))
            data.Add(file);
        return data;
    }

    [Theory]
    [MemberData(nameof(SkillFiles))]
    public void Skill_has_no_repository_only_references(string file)
    {
        var text = File.ReadAllText(file);
        string[] forbidden = ["usecases/", "src/Kompas", "kompas-sdk-research", "docs-maintainer", "docs/Kompas3D_SDK"];

        foreach (var token in forbidden)
            Assert.DoesNotContain(token, text, StringComparison.Ordinal);
    }

    [Theory]
    [MemberData(nameof(SkillFiles))]
    public void Skill_has_no_stale_tool_count(string file)
    {
        var text = File.ReadAllText(file);
        string[] staleCounts = ["46 инструментов", "83 инструмента", "84 инструмента"];

        foreach (var stale in staleCounts)
            Assert.DoesNotContain(stale, text, StringComparison.Ordinal);
    }

    [Theory]
    [MemberData(nameof(SkillFiles))]
    public void Skill_does_not_reference_merged_away_tools(string file)
    {
        var text = File.ReadAllText(file);
        // Инструменты, слитые в общие: навык, зовущий их по имени, стоит агенту потерянного хода.
        string[] gone =
        [
            "sketch_add_", "sketch_create_on_face", "sketch_create_on_offset_plane",
            "extrude_boss", "extrude_cut", "revolve_boss", "revolve_cut",
            "fillet_edge_index", "chamfer_edge_index",
            "hole_counterbore", "hole_countersink", "hole_conic",
            "linear_pattern", "circular_pattern", "mirror_operation", "mirror_body",
            "document_save_as", "create_variable", "set_variable_note",
            "get_part_info", "get_bounding_box", "describe_face", "describe_edge",
        ];

        foreach (var name in gone)
            Assert.DoesNotContain(name, text, StringComparison.Ordinal);
    }

    [Fact]
    public void Both_skills_are_present_with_frontmatter()
    {
        foreach (var name in new[] { "kompas-3d", "kompas-fdm-design" })
        {
            var path = Path.Combine(SkillsRoot, name, "SKILL.md");
            Assert.True(File.Exists(path), $"нет навыка {path}");

            var text = File.ReadAllText(path);
            Assert.StartsWith("---", text, StringComparison.Ordinal);
            Assert.Contains($"name: {name}", text, StringComparison.Ordinal);
            Assert.Contains("description:", text, StringComparison.Ordinal);
        }
    }
}
