"""Test-Double für `codex exec --json`. Verhalten über argv[1].

Wird nur von Tests über den echten SubprocessRunner gestartet. Enthält
keine echten Secrets; ein Fake-Token wird zur Laufzeit zusammengesetzt.
"""
import hashlib
import json
import os
import signal
import subprocess
import sys
import time


def emit(text: str) -> None:
    for event in (
        {"type": "thread.started", "thread_id": "fake"},
        {"type": "turn.started"},
        {"type": "item.completed", "item": {"id": "item_0", "type": "agent_message", "text": text}},
        {"type": "turn.completed", "usage": {"input_tokens": 1, "output_tokens": 1}},
    ):
        sys.stdout.write(json.dumps(event) + "\n")
    sys.stdout.flush()


def main() -> None:
    mode = sys.argv[1] if len(sys.argv) > 1 else "success"
    arg = sys.argv[2] if len(sys.argv) > 2 else ""
    if mode == "noread":
        # Liest stdin NICHT und beendet sofort erfolgreich -> der Schreiber bekommt EPIPE,
        # waehrend noch Prompt-Bytes ausstehen (Review #13).
        try:
            sys.stdin.buffer.close()
        except OSError:
            pass
        emit("NOREAD_OK")
        sys.exit(0)
    stdin = sys.stdin.buffer.read()
    if mode == "success":
        emit("MOCK_OK")
    elif mode == "echo":
        emit(stdin.decode("utf-8"))
    elif mode == "stdin_sha":
        emit("STDIN_SHA256=" + hashlib.sha256(stdin).hexdigest())
    elif mode == "exit2":
        sys.exit(2)
    elif mode == "sleep":
        time.sleep(float(arg or "30"))
        emit("LATE")
    elif mode == "crash":
        os.kill(os.getpid(), signal.SIGKILL)
    elif mode == "flood":
        sys.stdout.write("X" * int(arg or "100000"))
        sys.stdout.flush()
        time.sleep(30)
    elif mode == "flood_err":
        sys.stderr.write("E" * int(arg or "100000"))
        sys.stderr.flush()
        time.sleep(30)
    elif mode == "env":
        emit(json.dumps(dict(os.environ), sort_keys=True))
    elif mode == "cwd":
        emit(os.getcwd())
    elif mode == "files":
        root = os.path.join(os.getcwd(), "attachments")
        listing = []
        for name in sorted(os.listdir(root)):
            with open(os.path.join(root, name), "rb") as handle:
                listing.append(f"{name}:{hashlib.sha256(handle.read()).hexdigest()}")
        emit("\n".join(listing))
    elif mode == "grandchild":
        child = subprocess.Popen(["/bin/sleep", "30"])
        with open(arg, "w", encoding="utf-8") as handle:
            handle.write(str(child.pid))
        time.sleep(30)
    elif mode == "cpu":
        while True:
            pass
    elif mode == "mem":
        block = bytearray(int(arg))
        emit(f"ALLOCATED {len(block)}")
    elif mode == "tool":
        for event in (
            {"type": "turn.started"},
            {"type": "item.started", "item": {"type": "command_execution", "command": "id"}},
            {"type": "turn.completed"},
        ):
            sys.stdout.write(json.dumps(event) + "\n")
    elif mode == "secret":
        fake_token = "".join(str(d) for d in range(1, 10)) + ":" + "A" * 35
        emit(f"Hier ist dein Token: {fake_token} Ende.")
    elif mode == "big_answer":
        emit("Z" * int(arg or "20000"))
    else:
        sys.exit(64)


if __name__ == "__main__":
    main()
