using ScadaLink.CentralUI.ScriptAnalysis;

namespace ScadaLink.CentralUI.Tests.ScriptAnalysis;

public class JsonSchemaShapeParserTests
{
    // ── JSON Schema (post-migration) ─────────────────────────────────────────

    [Fact]
    public void Parameters_JsonSchema_ScalarsAndRequired()
    {
        const string json = """
            {"type":"object","properties":{
              "id":{"type":"integer"},
              "label":{"type":"string"},
              "active":{"type":"boolean"}
            },"required":["id","active"]}
            """;
        var result = JsonSchemaShapeParser.ParseParameters(json);

        Assert.Collection(result,
            p => { Assert.Equal("id", p.Name); Assert.Equal("Integer", p.Type); Assert.True(p.Required); },
            p => { Assert.Equal("label", p.Name); Assert.Equal("String", p.Type); Assert.False(p.Required); },
            p => { Assert.Equal("active", p.Name); Assert.Equal("Boolean", p.Type); Assert.True(p.Required); });
    }

    [Fact]
    public void Parameters_JsonSchema_ArrayOfStringsBecomesListString()
    {
        const string json = """
            {"type":"object","properties":{
              "tags":{"type":"array","items":{"type":"string"}}
            }}
            """;
        var result = JsonSchemaShapeParser.ParseParameters(json);

        var tags = Assert.Single(result);
        Assert.Equal("tags", tags.Name);
        Assert.Equal("List<String>", tags.Type);
        Assert.False(tags.Required);
    }

    [Fact]
    public void Return_JsonSchema_Number()
    {
        Assert.Equal("Float", JsonSchemaShapeParser.ParseReturnType(@"{""type"":""number""}"));
    }

    [Fact]
    public void Return_JsonSchema_ArrayOfIntegers()
    {
        Assert.Equal("List<Integer>",
            JsonSchemaShapeParser.ParseReturnType(@"{""type"":""array"",""items"":{""type"":""integer""}}"));
    }

    // ── Legacy flat shape (pre-migration safety net) ─────────────────────────

    [Fact]
    public void Parameters_Legacy_FlatArrayStillParses()
    {
        const string json = """[{"name":"x","type":"Integer"},{"name":"y","type":"String","required":false}]""";
        var result = JsonSchemaShapeParser.ParseParameters(json);

        Assert.Collection(result,
            p => { Assert.Equal("x", p.Name); Assert.Equal("Integer", p.Type); Assert.True(p.Required); },
            p => { Assert.Equal("y", p.Name); Assert.Equal("String", p.Type); Assert.False(p.Required); });
    }

    [Fact]
    public void Return_Legacy_ListSentinelStillParses()
    {
        Assert.Equal("List<String>",
            JsonSchemaShapeParser.ParseReturnType(@"{""type"":""List"",""itemType"":""String""}"));
    }

    // ── Edge cases ────────────────────────────────────────────────────────────

    [Fact]
    public void Parameters_Null_ReturnsEmpty()
    {
        Assert.Empty(JsonSchemaShapeParser.ParseParameters(null));
        Assert.Empty(JsonSchemaShapeParser.ParseParameters(""));
        Assert.Empty(JsonSchemaShapeParser.ParseParameters("   "));
    }

    [Fact]
    public void Parameters_Malformed_ReturnsEmpty()
    {
        Assert.Empty(JsonSchemaShapeParser.ParseParameters("{not json"));
        Assert.Empty(JsonSchemaShapeParser.ParseParameters("42"));
    }

    [Fact]
    public void Return_Null_ReturnsNull()
    {
        Assert.Null(JsonSchemaShapeParser.ParseReturnType(null));
        Assert.Null(JsonSchemaShapeParser.ParseReturnType(""));
    }

    [Fact]
    public void Parameters_SchemaWithNoProperties_ReturnsEmpty()
    {
        Assert.Empty(JsonSchemaShapeParser.ParseParameters(@"{""type"":""object""}"));
        Assert.Empty(JsonSchemaShapeParser.ParseParameters(@"{""type"":""object"",""properties"":{}}"));
    }
}
