"""Tests for feedback loop closer."""

import json
import tempfile
from pathlib import Path

import pytest

from oclawma.self_improvement.feedback_loop_closer import (
    CorrectionPattern,
    FeedbackLoopCloser,
)


class TestCorrectionPattern:
    """Tests for CorrectionPattern."""

    def test_pattern_creation(self):
        """Test creating a correction pattern."""
        pattern = CorrectionPattern(
            name="direct_correction",
            regex=r"^no[,.]?\s+",
            weight=1.0,
        )
        assert pattern.name == "direct_correction"
        assert pattern.weight == 1.0
        assert pattern.compiled_regex is not None

    def test_pattern_matching(self):
        """Test pattern matching."""
        pattern = CorrectionPattern(
            name="direct_correction",
            regex=r"^(?:no[,.]?\s+|actually[,.]?\s+)",
            weight=1.0,
        )
        assert pattern.compiled_regex.match("No, that's wrong")
        assert pattern.compiled_regex.match("Actually, use this")
        assert not pattern.compiled_regex.match("Yes, that's correct")


class TestFeedbackLoopCloser:
    """Tests for FeedbackLoopCloser."""

    @pytest.fixture
    def temp_dir(self):
        """Create temporary directory for tests."""
        with tempfile.TemporaryDirectory() as tmp:
            yield Path(tmp)

    @pytest.fixture
    def closer(self, temp_dir):
        """Create closer with temp paths."""
        return FeedbackLoopCloser(
            memory_dir=str(temp_dir),
            agents_file=str(temp_dir / "AGENTS.md"),
            tools_file=str(temp_dir / "TOOLS.md"),
            pending_file=str(temp_dir / "pending.json"),
        )

    def test_detect_correction(self, closer):
        """Test correction detection."""
        # Direct correction
        result = closer.detect_correction("No, use the other tool")
        assert result is not None
        assert result["confidence"] >= 0.7

        # No correction
        result = closer.detect_correction("That looks great!")
        assert result is None

    def test_categorize_lesson_tools(self, closer):
        """Test categorizing tool-related lessons."""
        result = closer.categorize_lesson("use git instead of svn")
        assert result["category"] == "tools"
        assert result["targetFile"] == "TOOLS.md"

    def test_categorize_lesson_behavior(self, closer):
        """Test categorizing behavior-related lessons."""
        result = closer.categorize_lesson("always check first")
        assert result["category"] == "behavior"

    def test_categorize_lesson_security(self, closer):
        """Test categorizing security-related lessons."""
        result = closer.categorize_lesson("expose the api token publicly")
        assert result["category"] == "security"

    def test_generate_rule(self, closer):
        """Test rule generation."""
        detection = {
            "lesson": "you should use git instead",
            "matchedText": "you should",
            "confidence": 0.9,
        }
        category = {"category": "tools"}

        rule = closer.generate_rule(detection, category)
        assert "use git instead" in rule["rule"].lower()
        assert rule["confidence"] == 0.9

    def test_queue_correction(self, closer, temp_dir):
        """Test queueing a correction."""
        result = closer.queue_correction("No, use Python instead of bash")

        assert result is not None
        assert "id" in result
        assert result["confidence"] >= closer.min_confidence

        # Verify it was saved
        data = json.loads(closer.pending_file.read_text())
        assert len(data["pending"]) == 1

    def test_reject_correction(self, closer):
        """Test rejecting a correction."""
        # Queue first
        result = closer.queue_correction("No, use Python instead")
        correction_id = result["id"]

        # Reject
        closer.reject_correction(correction_id)

        # Verify
        data = json.loads(closer.pending_file.read_text())
        assert len(data["pending"]) == 0
        assert len(data["applied"]) == 1
        assert data["applied"][0]["status"] == "rejected"

    def test_default_patterns(self):
        """Test default patterns are loaded."""
        closer = FeedbackLoopCloser()
        assert len(closer.correction_patterns) > 0

        pattern_names = [p.name for p in closer.correction_patterns]
        assert "direct_correction" in pattern_names
        assert "should_have" in pattern_names
        assert "not_correct" in pattern_names
