import pytest


def _spec():
    return {
        "openapi": "3.0.0",
        "servers": [{"url": "https://example.com"}],
        "paths": {
            "/pets": {
                "post": {
                    "requestBody": {
                        "required": True,
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "additionalProperties": False,
                                    "required": ["name", "age", "tags"],
                                    "properties": {
                                        "name": {"type": "string", "minLength": 2, "maxLength": 5},
                                        "age": {"type": "integer", "minimum": 0, "maximum": 120},
                                        "tags": {
                                            "type": "array",
                                            "minItems": 1,
                                            "maxItems": 2,
                                            "items": {"type": "string", "minLength": 1},
                                        },
                                    },
                                }
                            }
                        },
                    },
                    "responses": {"200": {"description": "ok"}},
                }
            }
        },
    }


def test_openapi_fuzzer_generates_valid_and_invalid_cases():
    jsonschema = pytest.importorskip("jsonschema")

    from ai_testing_swarm.core.openapi_fuzzer import (
        generate_request_body_fuzz_cases,
        get_request_body_schema,
    )

    spec = _spec()
    schema = get_request_body_schema(spec=spec, path="/pets", method="POST")
    assert schema and schema.get("type") == "object"

    cases = generate_request_body_fuzz_cases(spec=spec, path="/pets", method="POST", max_valid=10, max_invalid=10)
    assert any(c.is_valid for c in cases)
    assert any(not c.is_valid for c in cases)

    resolver = jsonschema.RefResolver.from_schema(spec)  # type: ignore[attr-defined]
    cls = jsonschema.validators.validator_for(schema)  # type: ignore[attr-defined]
    v = cls(schema, resolver=resolver)

    for c in cases:
        if c.is_valid:
            v.validate(c.body)
        else:
            with pytest.raises(Exception):
                v.validate(c.body)


def test_planner_includes_openapi_fuzz_cases(monkeypatch):
    pytest.importorskip("jsonschema")

    from ai_testing_swarm.agents.test_planner_agent import TestPlannerAgent
    import ai_testing_swarm.core.config as config

    # Ensure enabled in this test regardless of env at import time
    monkeypatch.setattr(config, "AI_SWARM_OPENAPI_FUZZ", True)
    monkeypatch.setattr(config, "AI_SWARM_OPENAPI_FUZZ_MAX_VALID", 3)
    monkeypatch.setattr(config, "AI_SWARM_OPENAPI_FUZZ_MAX_INVALID", 3)
    monkeypatch.setattr(config, "AI_SWARM_OPENAPI_FUZZ_MAX_DEPTH", 5)

    request = {
        "method": "POST",
        "url": "https://example.com/pets",
        "headers": {"content-type": "application/json"},
        "params": {},
        "body": {},
        "_openapi": {"spec": _spec(), "path": "/pets", "method": "POST", "source": "inline"},
    }

    tests = TestPlannerAgent().plan(request)
    names = {t.get("name") for t in tests}
    assert any(str(n).startswith("openapi_") for n in names)
