#!/usr/bin/env python3
"""Pre-commit hook: enforce that journal_quality.db is opened read-only.

The compiled journal-quality DB has exactly one writer — `build_db()` in
`src/local_deep_research/journal_quality/db.py`. Every other consumer
must open the file with SQLite URI flag `mode=ro` (and ideally also
`immutable=1`).

This hook scans staged Python files for opens of `journal_quality.db`
or the legacy `journal_reference.db` and fails the commit if any of
them is missing the `mode=ro` flag, OR if the open lives outside the
single allowed writer module.
"""

from __future__ import annotations

import re
import sys
from pathlib import Path

ALLOWED_WRITER = "src/local_deep_research/journal_quality/db.py"
DB_NAME_PATTERN = re.compile(r"journal_(quality|reference)\.db")
MODE_RO_PATTERN = re.compile(r"mode\s*=\s*ro", re.IGNORECASE)


def check_file(path: Path) -> list[str]:
    """Return list of human-readable error messages for `path`."""
    errors: list[str] = []
    if str(path).endswith(ALLOWED_WRITER):
        return errors  # the writer module is allowed to open writable
    if not path.suffix == ".py":
        return errors

    try:
        content = path.read_text(encoding="utf-8", errors="replace")
    except OSError:
        return errors

    for lineno, line in enumerate(content.splitlines(), start=1):
        if not DB_NAME_PATTERN.search(line):
            continue
        # Skip comments and string-literal references that aren't opens
        stripped = line.lstrip()
        if stripped.startswith("#"):
            continue
        # Skip lines that are just naming the file (e.g. f-strings used
        # for log messages, dict keys, file existence checks)
        is_open_call = any(
            tok in line
            for tok in (
                "sqlite3.connect",
                "create_engine",
                ".connect(",
                "open(",
            )
        )
        if not is_open_call:
            continue
        if not MODE_RO_PATTERN.search(line):
            errors.append(
                f"{path}:{lineno}: opens journal_quality.db without "
                f"mode=ro — only `journal_quality/db.py::build_db` may "
                f"open the file writable."
            )

    return errors


def main(argv: list[str]) -> int:
    files = [Path(p) for p in argv[1:]]
    if not files:
        return 0
    all_errors: list[str] = []
    for f in files:
        all_errors.extend(check_file(f))

    if all_errors:
        print(
            "ERROR: journal_quality.db read-only invariant violated:",
            file=sys.stderr,
        )
        for err in all_errors:
            print(f"  {err}", file=sys.stderr)
        print(
            "\nThe compiled journal-quality DB is read-only at runtime."
            " The only writer is `build_db()` in "
            f"{ALLOWED_WRITER}. Open the file with "
            'sqlite3.connect(f"file:{path}?mode=ro&immutable=1", uri=True)'
            " everywhere else.",
            file=sys.stderr,
        )
        return 1
    return 0


if __name__ == "__main__":
    sys.exit(main(sys.argv))
