#!/usr/bin/env python3
"""Tests for Story 3.01 (Track B): MVFLTrigger — 3-Condition Detection"""
import sys
sys.path.insert(0, '/mnt/e/genesis-system')


def test_mvfl_trigger():
    from core.mvfl.mvfl_trigger import MVFLTrigger, MVFLTriggerResult

    trigger = MVFLTrigger()

    # ------------------------------------------------------------------
    # Black-Box Tests
    # ------------------------------------------------------------------

    # BB1: HTTP 422 → external_rejection severity 3
    result = trigger.evaluate({"status_code": 422, "task_id": "t1", "status": "error"}, {})
    assert result.triggered is True, "BB1: should be triggered"
    assert result.trigger_type == "external_rejection", f"BB1: got {result.trigger_type}"
    assert result.severity == 3, f"BB1: severity should be 3, got {result.severity}"
    assert "422" in result.details, f"BB1: details should mention 422, got {result.details}"

    # BB2: status=completed with result=None → semantic severity 2
    result = trigger.evaluate({"task_id": "t2", "status": "completed", "result": None}, {})
    assert result.triggered is True, "BB2: should be triggered"
    assert result.trigger_type == "semantic", f"BB2: got {result.trigger_type}"
    assert result.severity == 2, f"BB2: severity should be 2, got {result.severity}"

    # BB3: Clean output → triggered=False
    result = trigger.evaluate({"task_id": "t3", "status": "completed", "result": "done"}, {})
    assert result.triggered is False, "BB3: should NOT be triggered"
    assert result.trigger_type is None, f"BB3: trigger_type should be None, got {result.trigger_type}"
    assert result.severity == 0, f"BB3: severity should be 0, got {result.severity}"

    # BB4: api_error present → external_rejection
    result = trigger.evaluate({"task_id": "t4", "api_error": "rate limited", "status": "error"}, {})
    assert result.triggered is True, "BB4: should be triggered"
    assert result.trigger_type == "external_rejection", f"BB4: got {result.trigger_type}"
    assert "rate limited" in result.details, f"BB4: details missing error, got {result.details}"

    # BB5: HTTP 500 → external_rejection severity 3
    result = trigger.evaluate({"status_code": 500, "task_id": "t8", "status": "error"}, {})
    assert result.triggered is True, "BB5: should be triggered"
    assert result.trigger_type == "external_rejection", f"BB5: got {result.trigger_type}"
    assert result.severity == 3, f"BB5: severity should be 3, got {result.severity}"

    # ------------------------------------------------------------------
    # White-Box Tests
    # ------------------------------------------------------------------

    # WB1: External takes priority over Semantic (both conditions present)
    result = trigger.evaluate(
        {
            "task_id": "t5",
            "status_code": 500,
            "status": "completed",   # creates semantic inconsistency too
            "result": None,          # further semantic issue
        },
        {},
    )
    assert result.trigger_type == "external_rejection", (
        f"WB1: External should take priority over Semantic, got {result.trigger_type}"
    )

    # WB2: trigger_type is None when triggered=False
    result = trigger.evaluate({"task_id": "t6", "status": "completed", "result": "ok"}, {})
    assert result.trigger_type is None, (
        f"WB2: trigger_type should be None for clean output, got {result.trigger_type}"
    )

    # WB3: Missing task_id → syntax trigger
    result = trigger.evaluate({"status": "completed", "result": "ok"}, {})
    assert result.triggered is True, "WB3: should be triggered"
    assert result.trigger_type == "syntax", f"WB3: got {result.trigger_type}"
    assert result.severity == 1, f"WB3: severity should be 1, got {result.severity}"
    assert "task_id" in result.details, f"WB3: details should mention missing field, got {result.details}"

    # WB4: Negative duration → semantic
    result = trigger.evaluate(
        {"task_id": "t7", "status": "completed", "result": "ok", "duration_ms": -5}, {}
    )
    assert result.triggered is True, "WB4: should be triggered"
    assert result.trigger_type == "semantic", f"WB4: got {result.trigger_type}"
    assert "-5" in result.details, f"WB4: details should mention negative value, got {result.details}"

    # WB5: explicit schema validation — required field missing
    schema = {"payload": {"required": True, "type": "dict"}}
    result = trigger.evaluate({"task_id": "t9", "status": "ok"}, {"expected_schema": schema})
    assert result.triggered is True, "WB5: should be triggered"
    assert result.trigger_type == "syntax", f"WB5: got {result.trigger_type}"
    assert "payload" in result.details, f"WB5: missing field should be named, got {result.details}"

    # WB6: explicit schema — type mismatch
    schema = {"count": {"required": True, "type": "int"}}
    result = trigger.evaluate(
        {"task_id": "t10", "status": "ok", "count": "not-an-int"},
        {"expected_schema": schema},
    )
    assert result.triggered is True, "WB6: should be triggered"
    assert result.trigger_type == "syntax", f"WB6: got {result.trigger_type}"
    assert "count" in result.details, f"WB6: field name should appear in details, got {result.details}"

    print("ALL TESTS PASSED — Story 3.01 (Track B)")


if __name__ == "__main__":
    test_mvfl_trigger()
