import hashlib
from pathlib import Path, PurePosixPath

def compute_sha256_streaming(file_path: Path, chunk_size: int = 65536) -> str:
    """Compute the SHA-256 hexadecimal digest in 64 KiB chunks."""
    hasher = hashlib.sha256()
    with file_path.open("rb") as f:
        while chunk := f.read(chunk_size):
            hasher.update(chunk)
    return hasher.hexdigest()

def parse_sha256_manifest(
    manifest_path: Path,
    base_dir: Path | None = None
) -> list[tuple[str, Path]]:
    """
    Parse a standard GNU sha256sum manifest file.
    Enforces simple relative filenames, rejects traversal, escapes, and duplicates.
    Requires Python 3.10+.
    """
    manifest_file = Path(manifest_path)
    base = (base_dir if base_dir is not None else manifest_file.parent).resolve()

    records: list[tuple[str, Path]] = []
    seen_targets: set[Path] = set()

    with manifest_file.open("r", encoding="utf-8") as f:
        for line_no, raw_line in enumerate(f, start=1):
            line = raw_line.rstrip("\r\n")
            if not line or line.startswith("#"):
                continue

            # GNU coreutils sha256sum prefixes escaped records with a backslash
            if line.startswith("\\"):
                raise ValueError(
                    f"Line {line_no}: Escaped filenames are unsupported in this parser"
                )

            # Standard format: exactly 64-hex digest + 2-char delimiter + filename
            if len(line) < 67:
                raise ValueError(
                    f"Line {line_no}: Record too short for sha256sum format"
                )

            digest_candidate = line[:64]
            sep_candidate = line[64:66]

            if sep_candidate not in ("  ", " *"):
                raise ValueError(
                    f"Line {line_no}: Missing standard '  ' or ' *' delimiter after digest"
                )

            if not all(c in "0123456789abcdefABCDEF" for c in digest_candidate):
                raise ValueError(f"Line {line_no}: Invalid 64-hex SHA-256 digest")

            raw_filename = line[66:]
            if not raw_filename:
                raise ValueError(f"Line {line_no}: Missing filename in manifest record")

            if "\x00" in raw_filename:
                raise ValueError(f"Line {line_no}: Embedded null byte prohibited")

            # Parse path purely without performing filesystem I/O or resolving symlinks yet
            rel_posix = PurePosixPath(raw_filename)
            if rel_posix.is_absolute():
                raise ValueError(f"Line {line_no}: Absolute paths are prohibited")

            if any(part in ("..", ".") for part in rel_posix.parts):
                raise ValueError(
                    f"Line {line_no}: Directory traversal or relative tokens prohibited"
                )

            # Conservative cross-platform names; reject drive and backslash syntax.
            if "\\" in raw_filename or ":" in raw_filename:
                raise ValueError(f"Line {line_no}: Unsupported filename syntax")
            if any(part in ("", ".", "..") for part in raw_filename.split("/")):
                raise ValueError(f"Line {line_no}: Empty or relative path component")
            target_path = (base / rel_posix).resolve()
            if not target_path.is_relative_to(base):
                raise ValueError(f"Line {line_no}: Resolved target escapes base directory")
            if target_path in seen_targets:
                raise ValueError(f"Line {line_no}: Duplicate target path {raw_filename}")
            seen_targets.add(target_path)

            records.append((digest_candidate.lower(), target_path))

    if not records:
        raise ValueError("Manifest contains no checksum records")

    return records

def verify_manifest(
    manifest_path: Path,
    base_dir: Path | None = None
) -> dict[str, str]:
    """
    Verify checksums for records declared in the manifest.
    Returns a dictionary mapping file path string to status ('OK', 'FAILED_CHECKSUM', 'MISSING').
    """
    results: dict[str, str] = {}
    records = parse_sha256_manifest(manifest_path, base_dir=base_dir)

    for expected_hash, file_path in records:
        key = str(file_path)
        # Note: In a trusted directory, checking is_file() verifies presence.
        # Concurrent hostile modifications are subject to TOCTOU race limitations.
        if not file_path.is_file():
            results[key] = "MISSING"
            continue

        actual_hash = compute_sha256_streaming(file_path)
        if actual_hash == expected_hash:
            results[key] = "OK"
        else:
            results[key] = "FAILED_CHECKSUM"

    return results
