"""Pytest result processing.

This module contains the PytestResultProcessor class that handles test result
processing, summary generation, and ToolResult building.
"""

from dataclasses import dataclass

from lintro.models.core.tool_result import ToolResult
from lintro.tools.implementations.pytest.pytest_config import PytestConfiguration
from lintro.tools.implementations.pytest.pytest_output_processor import (
    build_output_with_failures,
    check_total_time_warning,
    detect_and_log_flaky_tests,
    detect_and_log_slow_tests,
    process_test_summary,
)


@dataclass
class PytestResultProcessor:
    """Handles pytest result processing and ToolResult building.

    This class encapsulates the logic for processing test results, generating
    summaries, and building ToolResult objects from pytest execution data.

    Attributes:
        config: PytestConfiguration instance with result processing options.
        tool_name: Name of the tool (e.g., "pytest").
    """

    config: PytestConfiguration
    tool_name: str = "pytest"

    def process_test_results(
        self,
        output: str,
        return_code: int,
        issues: list,
        total_available_tests: int,
        docker_test_count: int,
        run_docker_tests: bool,
    ) -> tuple[dict, list]:
        """Process test results and generate summary.

        Args:
            output: Raw output from pytest.
            return_code: Return code from pytest.
            issues: Parsed test issues.
            total_available_tests: Total number of available tests.
            docker_test_count: Number of docker tests.
            run_docker_tests: Whether docker tests were enabled.

        Returns:
            Tuple[Dict, List]: Tuple of (summary_data, all_issues).
        """
        # Process summary
        summary_data = process_test_summary(
            output=output,
            issues=issues,
            total_available_tests=total_available_tests,
            docker_test_count=docker_test_count,
            run_docker_tests=run_docker_tests,
        )

        # Performance warnings (uses all issues including passed for duration info)
        detect_and_log_slow_tests(issues, self.config.get_options_dict())
        check_total_time_warning(
            summary_data["duration"],
            self.config.get_options_dict(),
        )

        # Flaky test detection
        detect_and_log_flaky_tests(issues, self.config.get_options_dict())

        # Return all issues - filtering for ToolResult.issues happens in build_result
        return (summary_data, issues)

    def build_result(
        self,
        success: bool,
        summary_data: dict,
        all_issues: list,
    ) -> ToolResult:
        """Build final ToolResult from processed data.

        Args:
            success: Whether tests passed.
            summary_data: Summary data dictionary.
            all_issues: List of all test issues (failures, errors, skips).

        Returns:
            ToolResult: Final result object.
        """
        # Filter to only failed/error issues for the ToolResult.issues field
        failed_issues = [
            issue for issue in all_issues if issue.test_status in ("FAILED", "ERROR")
        ]

        output_text = build_output_with_failures(summary_data, all_issues)

        result = ToolResult(
            name=self.tool_name,
            success=success,
            issues=failed_issues,
            output=output_text,
            issues_count=len(failed_issues),
        )

        # Store summary data for display in Execution Summary table
        result.pytest_summary = summary_data

        return result
