using Kompas.Mcp.Core.Modeling;

namespace Kompas.Mcp.Tests;

/// <summary>
/// Разбор и валидация примитивов. У слитого инструмента схема не запрещает лишние поля,
/// поэтому недостающий размер обязана назвать валидация — вместе с типом тела.
/// </summary>
[Trait("Category", "Unit")]
public sealed class PrimitivesTests
{
    [Theory]
    [InlineData("block", PrimitiveKind.Block)]
    [InlineData(" BOX ", PrimitiveKind.Block)]
    [InlineData("cylinder", PrimitiveKind.Cylinder)]
    [InlineData("sphere", PrimitiveKind.Sphere)]
    [InlineData("cone", PrimitiveKind.Cone)]
    public void Kind_names_and_aliases_are_recognized(string value, PrimitiveKind expected)
        => Assert.Equal(expected, Primitives.ParseKind(value));

    [Theory]
    [InlineData("", PrimitiveResult.NewBody)]
    [InlineData("new", PrimitiveResult.NewBody)]
    [InlineData("union", PrimitiveResult.Union)]
    [InlineData("subtract", PrimitiveResult.Subtract)]
    [InlineData("cut", PrimitiveResult.Subtract)]
    [InlineData("intersect", PrimitiveResult.Intersect)]
    public void Result_names_and_aliases_are_recognized(string value, PrimitiveResult expected)
        => Assert.Equal(expected, Primitives.ParseResult(value));

    [Fact]
    public void Unknown_kind_lists_the_allowed_ones()
    {
        var ex = Assert.Throws<ArgumentException>(() => Primitives.ParseKind("torus"));

        Assert.Contains("torus", ex.Message, StringComparison.Ordinal);
        Assert.Contains("cylinder", ex.Message, StringComparison.Ordinal);
    }

    [Fact]
    public void Block_names_the_missing_dimension()
    {
        var ex = Assert.Throws<ArgumentException>(
            () => Primitives.Validate(PrimitiveKind.Block, length: 10, width: null, height: 5, diameter: null));

        Assert.Contains("block", ex.Message, StringComparison.Ordinal);
        Assert.Contains("width", ex.Message, StringComparison.Ordinal);
    }

    [Fact]
    public void Cylinder_needs_diameter_and_height_not_length()
    {
        var ex = Assert.Throws<ArgumentException>(
            () => Primitives.Validate(PrimitiveKind.Cylinder, length: 10, width: 10, height: 5, diameter: null));

        Assert.Contains("diameter", ex.Message, StringComparison.Ordinal);
    }

    [Fact]
    public void Sphere_needs_only_the_diameter()
    {
        Primitives.Validate(PrimitiveKind.Sphere, length: null, width: null, height: null, diameter: 12);
    }

    [Fact]
    public void Non_positive_size_is_rejected_with_the_value()
    {
        var ex = Assert.Throws<ArgumentException>(
            () => Primitives.Validate(PrimitiveKind.Block, length: 10, width: 0, height: 5, diameter: null));

        Assert.Contains("width", ex.Message, StringComparison.Ordinal);
        Assert.Contains("> 0", ex.Message, StringComparison.Ordinal);
    }

    // Маппинг в COM-перечисления (ksObj3dTypeEnum / ksOperationResultEnum) проверяется
    // интеграционно — сборки КОМПАС в тестовом проекте недоступны без установленного CAD.
}
