# File: scripts/refactor/report_os_env_usage.py
# Purpose: Generate a CSV snapshot of os.getenv/os.environ usages for CONF-002 planning.
# Context: Complements migrate_os_getenv by quantifying remaining direct environment accesses.
"""CONF-002 usage reporter."""

from __future__ import annotations

import argparse
import csv
import re
from collections.abc import Iterable, Sequence
from dataclasses import dataclass
from pathlib import Path

PATTERN_GETENV = re.compile(r"\b(?:os|_os)\.getenv\s*\(")
PATTERN_ENVIRON_GET = re.compile(r"\bos\.environ\.get\s*\(")
PATTERN_ENVIRON_SUBSCRIPT = re.compile(r"\bos\.environ\s*\[")
PATTERN_ENVIRON_OTHER = re.compile(r"\bos\.environ(?!\s*\[|\.\s*get)\b")


@dataclass
class UsageRow:
    """Environment access counts for a single file."""

    path: Path
    getenv: int
    environ_get: int
    environ_other: int


def iter_python_files(targets: Sequence[Path]) -> list[Path]:
    """Return all Python files under the given targets."""

    files: list[Path] = []
    for target in targets:
        if target.is_file() and target.suffix == ".py":
            files.append(target)
            continue
        if target.is_dir():
            files.extend(path for path in target.rglob("*.py") if path.is_file())
    return sorted(set(files))


def collect_usage(targets: Sequence[Path]) -> list[UsageRow]:
    """Collect environment access counts for each Python file."""

    rows: list[UsageRow] = []
    for file_path in iter_python_files(targets):
        file_path = file_path.resolve()
        content = file_path.read_text(encoding="utf-8")
        getenv_count = len(PATTERN_GETENV.findall(content))
        environ_get_count = len(PATTERN_ENVIRON_GET.findall(content))
        environ_subscript_count = len(PATTERN_ENVIRON_SUBSCRIPT.findall(content))
        environ_other_count = len(PATTERN_ENVIRON_OTHER.findall(content))
        total = getenv_count + environ_get_count + environ_subscript_count + environ_other_count
        if total == 0:
            continue
        rows.append(
            UsageRow(
                path=file_path,
                getenv=getenv_count,
                environ_get=environ_get_count,
                environ_other=environ_subscript_count + environ_other_count,
            )
        )
    return sorted(rows, key=lambda row: str(row.path))


def write_csv(rows: Iterable[UsageRow], output_path: Path) -> None:
    """Write usage rows to the given CSV path."""

    output_path.parent.mkdir(parents=True, exist_ok=True)
    repo_root = Path(__file__).resolve().parents[2]
    with output_path.open("w", newline="", encoding="utf-8") as handle:
        writer = csv.writer(handle)
        writer.writerow(["path", "os.getenv", "os.environ.get", "os.environ[]"])
        for row in rows:
            try:
                relative = row.path.resolve().relative_to(repo_root)
            except ValueError:
                relative = row.path
            writer.writerow(
                [
                    str(relative).replace("\\", "/"),
                    row.getenv,
                    row.environ_get,
                    row.environ_other,
                ]
            )


def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        description="Generate a CSV of direct os.getenv/os.environ usages.",
    )
    parser.add_argument(
        "targets",
        nargs="*",
        default=["src/noveler"],
        help="Directories or files to scan (default: %(default)s).",
    )
    parser.add_argument(
        "--output",
        default="reports/conf_phase1_os_env_targets.csv",
        help="Path to the CSV report (default: %(default)s).",
    )
    return parser.parse_args(argv)


def main(argv: Sequence[str] | None = None) -> int:
    """Entry point for CLI execution."""

    args = parse_args(argv)
    targets = [Path(item).resolve() for item in args.targets]
    rows = collect_usage(targets)
    output_path = Path(args.output).resolve()
    write_csv(rows, output_path)
    print(f"Wrote {len(rows)} rows to {output_path}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
