from __future__ import annotations

import argparse
import json
import os
import pathlib
import signal
import subprocess
import sys
import time


def atomic_event(path: pathlib.Path | None, payload: dict[str, object]) -> None:
    if path is None:
        return
    payload = {**payload, "event_epoch": time.time_ns() / 1_000_000_000}
    path.parent.mkdir(parents=True, exist_ok=True)
    temporary = path.with_suffix(path.suffix + ".tmp")
    temporary.write_text(json.dumps(payload, sort_keys=True), encoding="utf-8")
    temporary.replace(path)


def emit(stream: object, byte_count: int, token: bytes) -> None:
    remaining = max(0, byte_count)
    writer = getattr(stream, "buffer", stream)
    chunk = token * 65536
    while remaining:
        block = chunk[: min(len(chunk), remaining)]
        writer.write(block)
        writer.flush()
        remaining -= len(block)


def sleeper(ignore_term: bool) -> int:
    if ignore_term and os.name != "nt":
        signal.signal(signal.SIGTERM, signal.SIG_IGN)
    time.sleep(60)
    return 0


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--bootstrapped-path", type=pathlib.Path)
    parser.add_argument("--ready-path", type=pathlib.Path)
    parser.add_argument("--stdout-bytes", type=int, default=0)
    parser.add_argument("--stderr-bytes", type=int, default=0)
    parser.add_argument("--ready-delay", type=float, default=0.0)
    parser.add_argument("--sleep-seconds", type=float, default=0.0)
    parser.add_argument("--detached-child", action="store_true")
    parser.add_argument("--sleeper", action="store_true")
    parser.add_argument("--ignore-term", action="store_true")
    args = parser.parse_args()
    if args.sleeper:
        return sleeper(args.ignore_term)
    atomic_event(args.bootstrapped_path, {"status": "BOOTSTRAPPED", "bootstrapped": True, "pid": os.getpid(), "phase": "python_started"})
    emit(sys.stdout, args.stdout_bytes, b"O")
    emit(sys.stderr, args.stderr_bytes, b"E")
    child: subprocess.Popen[bytes] | None = None
    if args.detached_child:
        kwargs: dict[str, object] = {}
        if os.name == "nt":
            kwargs["creationflags"] = getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0)
        else:
            kwargs["start_new_session"] = True
        child = subprocess.Popen([sys.executable, str(pathlib.Path(__file__).resolve()), "--sleeper", "--ignore-term"], **kwargs)
    time.sleep(max(0.0, args.ready_delay))
    atomic_event(args.ready_path, {"status": "READY", "ready": True, "pid": os.getpid(), "detached_pid": child.pid if child else None, "phase": "workload_ready", "intended_ready_delay_seconds": args.ready_delay})
    time.sleep(max(0.0, args.sleep_seconds))
    return 0


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