"""Test execution and reporting logic."""

from pathlib import Path
from typing import Dict, List, Optional, Tuple

import click

from guardrail.locator import FunctionInfo
from guardrail.report import FixPromptGenerator
from guardrail.runner import TestRunner


def run_and_report_tests(
    test_dir: Path,
    root: Path,
    function_test_map: Dict[FunctionInfo, Tuple[Path, str]],
    execute_command: bool,
) -> bool:
    """
    Run tests and report results.
    
    Returns:
        True if tests passed, False if they failed.
    """
    click.echo(f"\n🧪 Running generated tests...")
    test_runner = TestRunner(test_dir, root)
    passed, test_output, test_error = test_runner.run_tests()

    if passed:
        click.echo("✅ All tests passed!")
        return True

    # Tests failed - generate fix prompts
    click.echo("❌ Tests failed!")
    click.echo("\n" + "=" * 80)

    failing_tests = test_runner.get_failing_tests(test_output or "")
    fix_prompts = generate_fix_prompts(
        function_test_map, failing_tests, test_output, test_error
    )

    if fix_prompts:
        click.echo("\n".join(fix_prompts))
    else:
        click.echo("\nTest Output:")
        click.echo(test_output or test_error or "No output available")

    click.echo("\n" + "=" * 80)
    if execute_command:
        click.echo("\n🚫 Command execution blocked due to test failures.")
        click.echo("Please fix the failing tests and try again.")
    else:
        click.echo("\n⚠️  Tests failed. Please fix the issues before running your command.")

    return False


def generate_fix_prompts(
    function_test_map: Dict[FunctionInfo, Tuple[Path, str]],
    failing_tests: List[str],
    test_output: str,
    test_error: Optional[str],
) -> List[str]:
    """Generate fix prompts for failing tests."""
    fix_prompts = []

    for func, (test_path, test_code) in function_test_map.items():
        test_name = test_path.stem
        if any(test_name in ft for ft in failing_tests):
            failure_output = test_output or test_error or "Test execution failed"
            prompt = FixPromptGenerator.generate_fix_prompt(
                function=func,
                test_code=test_code,
                failure_output=failure_output[:1000],
                test_file_path=test_path,
            )
            fix_prompts.append(prompt)

    return fix_prompts

