#!/usr/bin/env python3
"""Test-only scope-entry dry-run harness. Not installed to production paths."""

from __future__ import annotations

import argparse
import os
import sys

_LIB = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "lib")
if _LIB not in sys.path:
    sys.path.insert(0, _LIB)

from seat_scope_entry import (  # noqa: E402
    ScopeEntryPaths,
    build_arg_parser,
    die,
    ns_inode,
    run_scope,
    validate_args,
    validate_static,
)
from seat_implementer_identity import implementer_username_for_seat  # noqa: E402


def resolve_fixture_target(home: str) -> tuple[str, int, int, str]:
    user = os.environ.get("SCOPE_FIXTURE_USER", "fixture-user")
    uid = int(os.environ.get("SCOPE_FIXTURE_UID", "1000"))
    gid = int(os.environ.get("SCOPE_FIXTURE_GID", "1000"))
    return user, uid, gid, home


def resolve_fixture_implementer(seat_id: str) -> tuple[str, int, int, str]:
    uid = int(os.environ.get("SCOPE_FIXTURE_IMPLEMENTER_UID", "999"))
    gid = int(os.environ.get("SCOPE_FIXTURE_IMPLEMENTER_GID", "999"))
    return implementer_username_for_seat(seat_id), uid, gid, f"/var/lib/overdeck/seat-runtime/{seat_id}/home"


def main() -> None:
    parser = argparse.ArgumentParser(prog="scope-entry-fixture")
    parser.add_argument("--fixture-root", required=True)
    parser.add_argument("--dry-run", action="store_true")
    parser.add_argument("--blocking", action="store_true")
    parser.add_argument("--dry-sleep", type=float, default=1.0)
    args, remainder = parser.parse_known_args()

    entry = build_arg_parser()
    try:
        ns = entry.parse_args(remainder)
    except SystemExit:
        die("unknown arg", 2)

    validate_static(ns)

    root = os.path.abspath(args.fixture_root)
    mock_bin = os.path.join(root, "bin")
    proc_root = os.path.join(root, "proc")
    cgroup_root = os.path.join(root, "sys/fs/cgroup")
    home = os.path.join(root, "home")
    seat_id = ns.seat_id

    paths = ScopeEntryPaths(
        proc_root=proc_root,
        cgroup_root=cgroup_root,
        tmux=os.path.join(mock_bin, "tmux"),
        systemd_run=os.path.join(mock_bin, "systemd-run"),
        systemctl=os.path.join(mock_bin, "systemctl"),
        implementer_exec=os.path.join(mock_bin, "overdeck-seat-implementer-exec"),
        tmux_mediator=os.path.join(mock_bin, "overdeck-seat-tmux-mediator"),
        sudo=os.path.join(mock_bin, "sudo"),
        dry_sleep_sec=args.dry_sleep,
    )

    validate_args(ns, home, skip_host_checks=True)
    inode = ns_inode(os.path.join(root, "var/run/netns", f"overdeck-seat-{seat_id}"))

    operator_user, operator_uid, operator_gid, operator_home = resolve_fixture_target(home)
    implementer_user, implementer_uid, implementer_gid, _ = resolve_fixture_implementer(seat_id)
    implementer_home_path = os.path.join(root, "var/lib/overdeck/seat-runtime", seat_id, "home")
    control_base = os.path.join(root, "var/lib/overdeck/seat-control")
    runtime_base = os.path.join(root, "var/lib/overdeck/seat-runtime")
    os.makedirs(implementer_home_path, mode=0o700, exist_ok=True)
    os.makedirs(control_base, mode=0o711, exist_ok=True)
    os.chmod(control_base, 0o711)
    os.environ["OVERDECK_SEAT_CONTROL_BASE"] = control_base
    os.environ["OVERDECK_SEAT_RUNTIME_BASE"] = runtime_base
    os.environ["OVERDECK_SEAT_TEST_MODE"] = "1"

    run_scope(
        paths=paths,
        unit=ns.unit,
        slice_name=ns.slice,
        socket=ns.socket,
        launcher=ns.launcher,
        claude_bin=ns.claude_bin,
        guard_bin=ns.guard_bin,
        checkout=ns.checkout,
        state_dir=os.path.dirname(ns.socket),
        seat_id=ns.seat_id,
        seat_host=ns.seat_host,
        seat_model=ns.seat_model,
        netns_inode=inode,
        operator_user=operator_user,
        operator_uid=operator_uid,
        operator_home=operator_home,
        implementer_user=implementer_user,
        implementer_uid=implementer_uid,
        implementer_gid=implementer_gid,
        implementer_home_path=implementer_home_path,
        dry_run=ns.dry_run or args.dry_run,
    )


if __name__ == "__main__":
    main()
