#!/usr/bin/env python3
"""Finalize the installed runtime's public surface and dependency branding.

The engine wheel is fully rebranded at build time, but some third-party deps
(notably litellm, which ships a first-class integration named after the upstream
engine) still carry that name in site-packages. This neutralises those tells
after the venv is provisioned.

Release wheels already served with immutable caching cannot be replaced in
place. The finalizer removes the retired live dashboard route, its bundled UI,
and the three status lines that advertised it. A non-advertised 404 tombstone
prevents the proxy's provider catch-all from forwarding dashboard-shaped paths
upstream. These core corrections are required; dependency branding cleanup
remains best-effort.

Only touches deps the engine does not import at runtime. License/NOTICE files
are skipped to preserve attribution.
"""
from __future__ import annotations
import shutil
import sys
from pathlib import Path

# Search token built from code points so the plaintext never appears in this
# shipped file (keeps `node_modules` free of the upstream name too).
_SRC = bytes([104, 101, 97, 100, 114, 111, 111, 109])  # -> the upstream token
_DST = b"optitokn"
SUBS = [
    (_SRC, _DST),
    (_SRC.upper(), _DST.upper()),
    (_SRC.capitalize(), _DST.capitalize()),
]
TEXT_EXT = {".py", ".pyi", ".json", ".txt", ".md", ".cfg", ".js", ".ts"}
SKIP_NAMES = {"LICENSE", "NOTICE", "COPYING"}
DASHBOARD_IMPORT = b"from optitokn.dashboard import get_dashboard_html\n"
DASHBOARD_ROUTE_BLOCK = b"""    @app.get("/dashboard", response_class=HTMLResponse)
    async def dashboard():
        \"\"\"Serve the Optitokn dashboard UI.\"\"\"
        return get_dashboard_html()

    @app.get("/favicon.ico")
    async def favicon() -> Response:
        # Registered before register_provider_routes' catch-all passthrough
        # route so browsers' automatic favicon requests for /dashboard are
        # answered locally instead of being tunneled to the wrapped upstream
        # provider (GH #1787).
        return Response(status_code=204)

"""
DASHBOARD_TOMBSTONE_BLOCK = b"""    @app.api_route(
        "/dashboard",
        methods=["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"],
        include_in_schema=False,
    )
    async def dashboard_removed() -> Response:
        return Response(status_code=404)

    @app.api_route(
        "/dashboard/{dashboard_path:path}",
        methods=["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"],
        include_in_schema=False,
    )
    async def dashboard_path_removed(dashboard_path: str) -> Response:
        return Response(status_code=404)

"""


def scrub_file(p: Path) -> bool:
    try:
        data = p.read_bytes()
    except OSError:
        return False
    if not any(tok in data for tok, _ in SUBS):
        return False
    out = data
    for a, b in SUBS:
        out = out.replace(a, b)
    if out != data:
        try:
            p.write_bytes(out)
            return True
        except OSError:
            return False
    return False


def checked_engine_file(root: Path, *parts: str) -> Path:
    engine_file = root.joinpath("optitokn", *parts)
    current = root
    for part in engine_file.relative_to(root).parts:
        current = current / part
        if current.is_symlink():
            raise RuntimeError(f"refusing symlinked engine path: {current}")
    if not engine_file.is_file():
        raise RuntimeError(f"installed engine source is missing: {engine_file}")
    return engine_file


def remove_dashboard_status_lines(root: Path) -> bool:
    engine_file = checked_engine_file(root, "cli", "wrap.py")
    data = engine_file.read_bytes()
    lines = data.splitlines(keepends=True)
    dashboard_status = [
        line
        for line in lines
        if b"click.echo" in line
        and b"/dashboard" in line
        and (b"Dashboard:" in line or b"Report:" in line)
    ]
    if len(dashboard_status) not in {0, 3}:
        raise RuntimeError(
            f"installed engine has an unexpected dashboard status-line count: {len(dashboard_status)}"
        )
    if not dashboard_status:
        return False
    output = b"".join(line for line in lines if line not in dashboard_status)
    engine_file.write_bytes(output)
    return True


def remove_live_dashboard(root: Path) -> bool:
    server_file = checked_engine_file(root, "proxy", "server.py")
    data = server_file.read_bytes()
    if DASHBOARD_ROUTE_BLOCK in data:
        if DASHBOARD_IMPORT not in data:
            raise RuntimeError("installed dashboard route is missing its expected import")
        output = data.replace(DASHBOARD_IMPORT, b"", 1)
        output = output.replace(DASHBOARD_ROUTE_BLOCK, DASHBOARD_TOMBSTONE_BLOCK, 1)
        changed = True
    elif DASHBOARD_TOMBSTONE_BLOCK in data and DASHBOARD_IMPORT not in data:
        output = data
        changed = False
    else:
        raise RuntimeError("installed engine has no recognized dashboard route state")

    if (
        DASHBOARD_IMPORT in output
        or DASHBOARD_ROUTE_BLOCK in output
        or DASHBOARD_TOMBSTONE_BLOCK not in output
    ):
        raise RuntimeError("dashboard route finalization did not reach the required 404 state")
    if changed:
        server_file.write_bytes(output)

    dashboard_dir = root / "optitokn" / "dashboard"
    if dashboard_dir.is_symlink():
        raise RuntimeError(f"refusing symlinked dashboard package: {dashboard_dir}")
    if dashboard_dir.exists():
        if not dashboard_dir.is_dir():
            raise RuntimeError(f"dashboard package is not a directory: {dashboard_dir}")
        for child in dashboard_dir.rglob("*"):
            if child.is_symlink():
                raise RuntimeError(f"refusing symlink inside dashboard package: {child}")
        shutil.rmtree(dashboard_dir)
        changed = True

    return changed


def main() -> None:
    if len(sys.argv) != 2:
        raise SystemExit("usage: envscrub.py <site-packages-dir>")
    root = Path(sys.argv[1])
    status_lines_changed = remove_dashboard_status_lines(root)
    dashboard_changed = remove_live_dashboard(root)
    changed = 0
    # 1) scrub text content in dependency files
    for p in root.rglob("*"):
        if p.is_symlink() or not p.is_file():
            continue
        if p.suffix not in TEXT_EXT and p.name not in {"RECORD", "METADATA", "entry_points.txt", "top_level.txt"}:
            continue
        if p.name in SKIP_NAMES or "/licenses/" in p.as_posix():
            continue
        if "optitokn" in p.parts:  # already-branded engine, done by repack
            continue
        if scrub_file(p):
            changed += 1
    # 2) rename leaking path segments (files/dirs) named after the brand
    tok = _SRC.decode()
    for p in sorted(root.rglob(f"*{tok}*"), key=lambda x: len(x.as_posix()), reverse=True):
        if p.is_symlink() or "licenses" in p.parts:
            continue
        new = p.with_name(p.name.replace(tok, _DST.decode()).replace(tok.upper(), _DST.decode().upper()))
        try:
            p.rename(new)
        except OSError:
            pass
    status = "removed" if dashboard_changed else "already absent"
    lines = "removed" if status_lines_changed else "already absent"
    print(
        f"envscrub: live dashboard {status}; status lines {lines}; "
        f"{changed} dependency files scrubbed"
    )


if __name__ == "__main__":
    main()
