"""Extended tests for test_runner.validate.comparator.

Covers errors_match, _match_type_from_level, and compare_results
argument pass-through not tested in test_comparator.py.
"""

from __future__ import annotations

from unittest.mock import MagicMock, patch

import pytest

from test_runner.common.config import ValidationConfiguration
from test_runner.common.models import ComparisonResult
from test_runner.validate.comparator import (
    _match_type_from_level,
    compare_results,
    errors_match,
)


# ---------------------------------------------------------------------------
# errors_match
# ---------------------------------------------------------------------------

class TestErrorsMatch:
    def test_identical_errors_match(self):
        assert errors_match("TIMEOUT: connection lost", "TIMEOUT: something else") is True

    def test_different_error_types_do_not_match(self):
        assert errors_match("TIMEOUT: lost", "SYNTAX: bad SQL") is False

    def test_both_empty_match(self):
        assert errors_match("", "") is True

    def test_one_empty_does_not_match(self):
        assert errors_match("", "ERROR: something") is False
        assert errors_match("ERROR: something", "") is False

    def test_case_insensitive(self):
        assert errors_match("timeout: lost", "TIMEOUT: something") is True

    def test_leading_whitespace_stripped(self):
        assert errors_match("  TIMEOUT: lost", "TIMEOUT: connection") is True

    def test_no_colon_full_string_used(self):
        assert errors_match("TIMEOUT", "TIMEOUT") is True
        assert errors_match("TIMEOUT", "SYNTAX") is False

    def test_multicolon_only_first_segment_used(self):
        assert errors_match("ERR:TYPE:detail", "ERR:OTHER:detail") is True


# ---------------------------------------------------------------------------
# _match_type_from_level
# ---------------------------------------------------------------------------

class TestMatchTypeFromLevel:
    def test_schema_validation(self):
        from snowflake.snowflake_data_validation.utils.constants import ValidationLevel
        assert _match_type_from_level(ValidationLevel.SCHEMA_VALIDATION.value) == "schema_mismatch"

    def test_metrics_validation(self):
        from snowflake.snowflake_data_validation.utils.constants import ValidationLevel
        assert _match_type_from_level(ValidationLevel.METRICS_VALIDATION.value) == "metrics_mismatch"

    def test_row_validation(self):
        from snowflake.snowflake_data_validation.utils.constants import ValidationLevel
        assert _match_type_from_level(ValidationLevel.ROW_VALIDATION.value) == "data_mismatch"

    def test_none_returns_unknown(self):
        assert _match_type_from_level(None) == "unknown"

    def test_empty_returns_unknown(self):
        assert _match_type_from_level("") == "unknown"

    def test_unrecognized_returns_unknown(self):
        assert _match_type_from_level("custom_level") == "unknown"


# ---------------------------------------------------------------------------
# compare_results -- argument pass-through
# ---------------------------------------------------------------------------

class TestCompareResultsPassthrough:
    @patch("test_runner.validate.comparator.InMemoryResultComparator")
    @patch("test_runner.validate.comparator.ResultComparator")
    def test_dump_baseline_and_actual_passed_to_in_memory(self, MockResult, MockInMemory):
        MockInMemory.return_value.compare.return_value = ComparisonResult(
            match=True, match_type="data_match",
        )
        cfg = MagicMock()
        cfg.validation_database = "DB"
        cfg.validation_configuration = ValidationConfiguration(
            in_memory_row_threshold=10_000,
        )
        bl = MagicMock()
        bl.row_counts = [5]

        compare_results(
            cfg, MagicMock(), "CALL P()", "h", "P",
            baseline=bl,
            dump_baseline_and_actual=True,
        )

        compare_call = MockInMemory.return_value.compare.call_args
        assert compare_call.kwargs.get("dump_baseline_and_actual") is True

    @patch("test_runner.validate.comparator.InMemoryResultComparator")
    @patch("test_runner.validate.comparator.ResultComparator")
    def test_outputs_args_passed_to_in_memory(self, MockResult, MockInMemory):
        MockInMemory.return_value.compare.return_value = ComparisonResult(
            match=True, match_type="data_match",
        )
        cfg = MagicMock()
        cfg.validation_database = "DB"
        cfg.validation_configuration = ValidationConfiguration(
            in_memory_row_threshold=10_000,
        )
        bl = MagicMock()
        bl.row_counts = []

        compare_results(
            cfg, MagicMock(), "CALL P()", "h", "P",
            baseline=bl,
            outputs_only=True,
            outputs_sql="BEGIN SELECT 1; END;",
        )

        compare_call = MockInMemory.return_value.compare.call_args
        assert compare_call.kwargs.get("outputs_only") is True
        assert compare_call.kwargs.get("outputs_sql") == "BEGIN SELECT 1; END;"
