from integrations.cli_wrappers.claude_code.detection.permission_detector import (
    PermissionDetector,
)


def test_permission_detector_extracts_mixed_menu_layout() -> None:
    detector = PermissionDetector()
    buffer_text = """
Do you want to make this edit to ask_user_question_panel.dart?
❯ 1. Yes

2. Yes, allow all edits during this session (shift+tab)
3. No
(esc to cancel)
"""

    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    assert (
        result.data["question"]
        == "Do you want to make this edit to ask_user_question_panel.dart?"
    )
    assert result.data["options"] == [
        "1. Yes",
        "2. Yes, allow all edits during this session (shift+tab)",
        "3. No",
    ]


def test_permission_detector_repairs_corrupted_terminal_redraw_text() -> None:
    """Test that detector can still parse text with some formatting issues.

    Note: With TerminalRenderer, garbled text is now fixed at the rendering level.
    This test now verifies that the detector can handle slightly malformed but
    still readable text (missing spaces due to terminal rendering quirks).
    """
    detector = PermissionDetector()
    # Updated: Text should be readable after TerminalRenderer processes it
    # This represents text that might have minor spacing issues but is still parseable
    buffer_text = """
Do you want to make this edit to ask_user_question_panel.dart?
❯ 1. Yes
  2. Yes, allow all edits during this session (shift+tab)
  3. No
(esc to cancel)
"""

    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    assert (
        result.data["question"]
        == "Do you want to make this edit to ask_user_question_panel.dart?"
    )
    assert result.data["options"] == [
        "1. Yes",
        "2. Yes, allow all edits during this session (shift+tab)",
        "3. No",
    ]


def test_permission_detector_keeps_terminal_option_count() -> None:
    detector = PermissionDetector()
    buffer_text = """
Do you want to run this command?
1. Yes
2. No
(esc to cancel)
"""

    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    assert result.data["options"] == ["1. Yes", "2. No"]


def test_permission_detector_keeps_first_option_when_question_repeats() -> None:
    detector = PermissionDetector()
    buffer_text = """
Do you want to make this edit to README.md?
❯ 1. Yes
Do you want to make this edit to README.md?
  2. Yes, allow all edits during this session (shift+tab)
  3. No
"""

    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    assert result.data["options"] == [
        "1. Yes",
        "2. Yes, allow all edits during this session (shift+tab)",
        "3. No",
    ]


def test_permission_detector_recovers_missing_first_option_from_fallback() -> None:
    detector = PermissionDetector()
    buffer_text = """
Do you want to make this edit to README.md?

❯ 1. Yes

Do you want to make this edit to README.md?
2. Yes, allow all edits during this session (shift+tab)
3. No
"""

    # Simulate a parse where direct scan can pick 2/3 first and fallback must recover 1.
    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    assert result.data["options"] == [
        "1. Yes",
        "2. Yes, allow all edits during this session (shift+tab)",
        "3. No",
    ]


def test_permission_detector_infers_primary_yes_when_options_start_at_two() -> None:
    detector = PermissionDetector()
    buffer_text = """
Do you want to make this edit to README.md?
2. Yes, allow all edits during this session (shift+tab)
3. No
"""

    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    assert result.data["options"] == [
        "1. Yes",
        "2. Yes, allow all edits during this session (shift+tab)",
        "3. No",
    ]


def test_permission_detector_extracts_context_for_skill() -> None:
    """Test that context above the question is captured for Skill permissions."""
    detector = PermissionDetector()
    buffer_text = """
──────────────────────────────────────────────────────────────────────
 Use skill "gsd:map-codebase"?
 Claude may use instructions, code, or files from this Skill.

   Analyze codebase with parallel mapper agents to produce .planning/codebase/ documents

 Do you want to proceed?
 ❯ 1. Yes
   2. Yes, and don't ask again for gsd:map-codebase in /Users/test/project
   3. No

 Esc to cancel · Tab to amend
"""

    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    # Question should include the context
    assert 'Use skill "gsd:map-codebase"?' in result.data["question"]
    assert "Analyze codebase with parallel mapper agents" in result.data["question"]
    assert result.data["options"] == [
        "1. Yes",
        "2. Yes, and don't ask again for gsd:map-codebase in /Users/test/project",
        "3. No",
    ]


def test_permission_detector_extracts_context_for_bash() -> None:
    """Test that context above the question is captured for Bash permissions."""
    detector = PermissionDetector()
    buffer_text = """
──────────────────────────────────────────────────────────────────────
 Bash command

   ls -la .planning/codebase/ && wc -l .planning/codebase/*.md
   Verify all codebase documents created

 Do you want to proceed?
 ❯ 1. Yes
   2. Yes, and don't ask again for: ls -la .planning/codebase/ && wc -l .planning/codebase/*.md
   3. No

 Esc to cancel · Tab to amend
"""

    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    # Question should include the bash command context
    assert "Bash command" in result.data["question"]
    assert "ls -la .planning/codebase/" in result.data["question"]
    assert "Verify all codebase documents created" in result.data["question"]
    assert result.data["options"] == [
        "1. Yes",
        "2. Yes, and don't ask again for: ls -la .planning/codebase/ && wc -l .planning/codebase/*.md",
        "3. No",
    ]


def test_permission_detector_with_ansi_sequences() -> None:
    """Test that ANSI sequences are properly cleaned from questions."""
    detector = PermissionDetector()

    # Test case: ANSI sequences mixed into question text
    # This simulates what might happen with cursor movements or insertions
    buffer_text = """
Do you want to create test.txt?
❯ 1. Yes
  2. No
"""

    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    assert "Do you want to create test.txt?" in result.data["question"]


def test_permission_detector_fixes_garbled_edit_prompts() -> None:
    """Test that detector works with properly rendered text.

    With TerminalRenderer, garbled text is fixed at the rendering level.
    This test now verifies that the detector correctly processes
    well-formed permission prompts.
    """
    detector = PermissionDetector()

    # Test case 1: Properly rendered "make this edit" prompt
    buffer_text = """
Do you want to make this edit to test.txt?
❯ 1. Yes
  2. Yes, allow all edits during this session
  3. No
"""

    result = detector.detect_and_extract(buffer_text)

    assert result.detected is True
    assert result.data is not None
    assert result.data["question"] == "Do you want to make this edit to test.txt?"

    # Test case 2: Another properly rendered prompt
    buffer_text2 = """
Do you want to make this edit to file.py?
❯ 1. Yes
  2. No
"""

    result2 = detector.detect_and_extract(buffer_text2)

    assert result2.detected is True
    assert result2.data is not None
    assert result2.data["question"] == "Do you want to make this edit to file.py?"
