"""
Behavioral tests for Task-002: ValidationRunner.

Tests the ValidationRunner class that wraps maid-runner library calls for
manifest validation and subprocess execution for behavioral tests.
"""

import sys
from pathlib import Path
from unittest.mock import patch, Mock

# Add maid_agents package to path
sys.path.insert(0, str(Path(__file__).parent.parent))

from maid_agents.core.validation_runner import ValidationRunner, ValidationResult


def test_validation_result_creation():
    """Test ValidationResult can be instantiated."""
    result = ValidationResult(
        success=True, stdout="Validation passed", stderr="", errors=[]
    )

    assert isinstance(result.success, bool)
    assert isinstance(result.stdout, str)
    assert isinstance(result.stderr, str)
    assert isinstance(result.errors, list)


def test_validation_runner_instantiation():
    """Test ValidationRunner can be instantiated."""
    runner = ValidationRunner()
    assert runner is not None
    assert isinstance(runner, ValidationRunner)


def test_validate_manifest_method():
    """Test validate_manifest calls maid_runner.validate and returns correct result."""
    runner = ValidationRunner()

    # Mock the maid_runner.validate function
    mock_mr_result = Mock()
    mock_mr_result.success = True
    mock_mr_result.errors = []
    mock_mr_result.warnings = []
    mock_mr_result.manifest_slug = "task-001-test"

    with patch(
        "maid_agents.core.validation_runner.maid_validate",
        return_value=mock_mr_result,
    ) as mock_validate:
        result = runner.validate_manifest(
            "manifests/task-001-test.manifest.json", use_chain=False
        )

        # Verify maid_runner.validate was called correctly
        mock_validate.assert_called_once()
        call_kwargs = mock_validate.call_args
        assert call_kwargs[0][0] == "manifests/task-001-test.manifest.json"

    # Validate return type
    assert isinstance(result, ValidationResult)
    assert result.success is True
    assert hasattr(result, "stdout")
    assert hasattr(result, "stderr")


def test_validate_manifest_with_chain():
    """Test validate_manifest passes use_chain to maid_runner.validate."""
    runner = ValidationRunner()

    mock_mr_result = Mock()
    mock_mr_result.success = True
    mock_mr_result.errors = []
    mock_mr_result.warnings = []
    mock_mr_result.manifest_slug = "task-001-test"

    with patch(
        "maid_agents.core.validation_runner.maid_validate",
        return_value=mock_mr_result,
    ) as mock_validate:
        result = runner.validate_manifest(
            "manifests/task-001-test.manifest.json", use_chain=True
        )

        # Verify use_chain was passed through
        call_kwargs = mock_validate.call_args
        assert call_kwargs[1]["use_chain"] is True

    assert isinstance(result, ValidationResult)
    assert result.success is True


def test_validate_manifest_failure():
    """Test validate_manifest correctly converts errors from maid_runner result."""
    runner = ValidationRunner()

    mock_error = Mock()
    mock_error.message = "Artifact 'Foo' not defined in bar.py"

    mock_mr_result = Mock()
    mock_mr_result.success = False
    mock_mr_result.errors = [mock_error]
    mock_mr_result.warnings = []
    mock_mr_result.manifest_slug = "task-001-test"

    with patch(
        "maid_agents.core.validation_runner.maid_validate",
        return_value=mock_mr_result,
    ):
        result = runner.validate_manifest("manifests/task-001-test.manifest.json")

    assert result.success is False
    assert len(result.errors) == 1
    assert "Artifact 'Foo' not defined" in result.errors[0]
    assert "Artifact 'Foo' not defined" in result.stderr


def test_run_behavioral_tests_method():
    """Test run_behavioral_tests method exists and has correct signature."""
    runner = ValidationRunner()

    manifest_path = "manifests/task-001-test.manifest.json"

    # Mock file reading for manifest and subprocess for test execution
    with patch("builtins.open") as mock_open:
        mock_open.return_value.__enter__ = Mock(return_value=mock_open)
        mock_open.return_value.__exit__ = Mock(return_value=False)
        mock_open.read.return_value = (
            '{"validationCommand": ["pytest", "tests/", "-v"]}'
        )

        with patch(
            "json.load", return_value={"validationCommand": ["pytest", "tests/", "-v"]}
        ):
            with patch("subprocess.run") as mock_run:
                mock_result = Mock()
                mock_result.returncode = 0
                mock_result.stdout = "1 passed"
                mock_result.stderr = ""
                mock_run.return_value = mock_result

                result = runner.run_behavioral_tests(manifest_path)

    # Validate return type
    assert isinstance(result, ValidationResult)
    assert hasattr(result, "success")
