# tests/test_remediation.py
"""Tests for the RemediationEngine and REMEDIATION_DB."""

import pytest

from crashsense.core.remediation import REMEDIATION_DB, RemediationEngine


class TestRemediationDB:
    """Validate the static remediation database."""

    def test_all_entries_have_required_keys(self):
        required = {"title", "explanation", "steps", "severity"}
        for pattern, entry in REMEDIATION_DB.items():
            assert required.issubset(entry.keys()), f"{pattern} missing keys: {required - entry.keys()}"

    def test_severity_values(self):
        valid = {"critical", "high", "medium", "low"}
        for pattern, entry in REMEDIATION_DB.items():
            assert entry["severity"] in valid, f"{pattern} has invalid severity: {entry['severity']}"

    def test_steps_are_lists(self):
        for pattern, entry in REMEDIATION_DB.items():
            assert isinstance(entry["steps"], list), f"{pattern} steps is not a list"
            assert len(entry["steps"]) > 0, f"{pattern} has no steps"

    def test_known_patterns_exist(self):
        expected = [
            "INSUFFICIENT_BALANCE",
            "INSUFFICIENT_ALLOWANCE",
            "OUT_OF_GAS",
            "SLIPPAGE_EXCEEDED",
            "DEADLINE_EXPIRED",
            "ACCESS_DENIED",
            "CONTRACT_PAUSED",
            "NONCE_TOO_LOW",
            "REENTRANCY_GUARD",
            "PANIC_ERROR",
        ]
        for p in expected:
            assert p in REMEDIATION_DB, f"Missing pattern: {p}"


class TestRemediationEngine:
    def setup_method(self):
        self.engine = RemediationEngine()

    def test_single_pattern(self):
        results = self.engine.get_remediation(["INSUFFICIENT_BALANCE"])
        assert len(results) == 1
        assert results[0]["pattern"] == "INSUFFICIENT_BALANCE"

    def test_multiple_patterns(self):
        results = self.engine.get_remediation(["OUT_OF_GAS", "SLIPPAGE_EXCEEDED"])
        assert len(results) == 2

    def test_unknown_pattern(self):
        results = self.engine.get_remediation(["TOTALLY_UNKNOWN_PATTERN"])
        assert len(results) == 0

    def test_deduplication(self):
        results = self.engine.get_remediation(["INSUFFICIENT_BALANCE", "INSUFFICIENT_BALANCE"])
        assert len(results) == 1

    def test_severity_ordering(self):
        results = self.engine.get_remediation(["NEAR_GAS_LIMIT", "ARITHMETIC_OVERFLOW", "INSUFFICIENT_BALANCE"])
        severities = [r["severity"] for r in results]
        order = {"critical": 0, "high": 1, "medium": 2, "low": 3}
        assert severities == sorted(severities, key=lambda s: order.get(s, 9))

    def test_format_fixes_has_content(self):
        text = self.engine.format_fixes(["SLIPPAGE_EXCEEDED"])
        assert "Slippage" in text
        assert "Steps to fix" in text or "steps" in text.lower()

    def test_format_fixes_unknown(self):
        text = self.engine.format_fixes(["UNKNOWN_XYZ"])
        assert "No specific remediation" in text

    def test_format_fixes_includes_severity_icons(self):
        text = self.engine.format_fixes(["ARITHMETIC_OVERFLOW"])
        assert "🔴" in text
