import hashlib

from api.services.proof_carrying_validator import validate_assistant_proof


def test_file_claim_without_context_or_ledger_is_blocked():
    r = validate_assistant_proof(
        assistant_text="In backend/api/routes/complete.py it sets enable_tools_execution = ...",
        context_text="",
        context_manifest={},
        valid_ledger_ids=[],
        ledger_tool_names={},
    )
    assert r.ok is False
    assert "Missing inline citation" in r.reason


def test_file_mention_as_advice_is_allowed_without_ledger():
    r = validate_assistant_proof(
        assistant_text="Edit backend/api/routes/complete.py to add a guard.",
        context_text="",
        context_manifest={},
        valid_ledger_ids=[],
        ledger_tool_names={},
    )
    assert r.ok is True


def test_file_claim_allowed_if_path_in_context():
    ctx = "User pasted:\nbackend/api/routes/complete.py\nand asked about it"
    ctx_id = hashlib.sha256(ctx.encode("utf-8", errors="ignore")).hexdigest()[:12]
    r = validate_assistant_proof(
        assistant_text=f"In backend/api/routes/complete.py it defines complete_impl. [context:{ctx_id}]",
        context_text=ctx,
        context_manifest={ctx_id: "fullhash"},
        valid_ledger_ids=[],
        ledger_tool_names={},
    )
    assert r.ok is True


def test_search_claim_requires_search_ledger_kind():
    # Pretend a Read executed (ledger id exists) but the assistant claims grep/search.
    r = validate_assistant_proof(
        assistant_text="The grep shows 3 matches. [ledger:led_deadbeefcafebabe]",
        context_text="",
        context_manifest={},
        valid_ledger_ids=["led_deadbeefcafebabe"],
        ledger_tool_names={"led_deadbeefcafebabe": "Read"},
    )
    assert r.ok is False
    assert "search-grounded" in (r.reason or "").lower()


def test_basename_collision_does_not_count_as_context():
    # Two different files share the same basename; basename-only match should NOT grant context exception.
    ctx = "Paths:\nbackend/a/utils.py\nfrontend/b/utils.py\n"
    ctx_id = hashlib.sha256(ctx.encode("utf-8", errors="ignore")).hexdigest()[:12]
    r = validate_assistant_proof(
        assistant_text=f"In utils.py it sets X. [context:{ctx_id}]",
        context_text=ctx,
        context_manifest={ctx_id: "fullhash"},
        valid_ledger_ids=[],
        ledger_tool_names={},
    )
    assert r.ok is False
    assert "must cite a valid `[ledger:led_...]`" in (r.reason or "")


def test_code_block_with_valid_context_citation_passes():
    ctx = "User pasted code:\n```python\nprint('hi')\n```\n"
    ctx_id = hashlib.sha256(ctx.encode("utf-8", errors="ignore")).hexdigest()[:12]
    r = validate_assistant_proof(
        assistant_text=f"```python\nprint('hi')\n```\n[context:{ctx_id}]",
        context_text=ctx,
        context_manifest={ctx_id: "fullhash"},
        valid_ledger_ids=[],
        ledger_tool_names={},
    )
    assert r.ok is True


def test_ide_context_path_exempt_from_citation():
    """File paths injected by the IDE (e.g. Cursor's open_and_recently_viewed_files)
    should pass without any citation tag."""
    r = validate_assistant_proof(
        assistant_text="In backend/api/services/execution_ledger.py the make_ledger_record function generates IDs.",
        context_text="",
        context_manifest={},
        valid_ledger_ids=[],
        ledger_tool_names={},
        ide_context_paths={
            "/users/mvii/desktop/pcompresslr/backend/api/services/execution_ledger.py",
            "backend/api/services/execution_ledger.py",
        },
    )
    assert r.ok is True


def test_ide_context_path_suffix_match():
    """A short relative path in the assistant text should match a longer IDE absolute path."""
    r = validate_assistant_proof(
        assistant_text="The file api/routes/complete.py handles compression.",
        context_text="",
        context_manifest={},
        valid_ledger_ids=[],
        ledger_tool_names={},
        ide_context_paths={
            "/users/mvii/desktop/pcompresslr/backend/api/routes/complete.py",
        },
    )
    assert r.ok is True


def test_non_ide_path_still_requires_citation():
    """Paths NOT in the IDE set should still be blocked without citation."""
    r = validate_assistant_proof(
        assistant_text="In backend/api/routes/complete.py it sets enable_tools_execution = ...",
        context_text="",
        context_manifest={},
        valid_ledger_ids=[],
        ledger_tool_names={},
        ide_context_paths={
            "backend/api/services/execution_ledger.py",
        },
    )
    assert r.ok is False

