#!/usr/bin/env python3
# Copyright 2026 The IREE Authors
#
# Licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

"""Captures one process invocation with Tracy."""

from __future__ import annotations

import argparse
import datetime
import os
from pathlib import Path
import re
import shlex
import shutil
import signal
import socket
import subprocess
import sys
import tempfile
import time


def eprint(message: str) -> None:
    print(f"[iree-tracy-capture] {message}", file=sys.stderr)


def parse_arguments() -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        description="Starts tracy-capture, runs one command, and writes a .tracy file.",
    )
    parser.add_argument("--output-dir", type=Path, default=Path(".tracy"))
    parser.add_argument("--name")
    parser.add_argument("--port", type=int, default=0)
    parser.add_argument("--address", default="127.0.0.1")
    parser.add_argument("--capture-tool", type=Path)
    parser.add_argument("--capture-exit-timeout", type=float, default=10.0)
    parser.add_argument("command", nargs=argparse.REMAINDER)
    args = parser.parse_args()
    if args.command and args.command[0] == "--":
        args.command = args.command[1:]
    if not args.command:
        parser.error("expected -- <command> [args...]")
    return args


def sanitize_name(value: str) -> str:
    value = value.strip().replace("//", "").replace(":", "-").replace("/", "-")
    value = re.sub(r"[^A-Za-z0-9_.-]+", "-", value).strip("-")
    return value or "trace"


def choose_port(requested_port: int) -> int:
    if requested_port:
        return requested_port
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as listen_socket:
        listen_socket.bind(("127.0.0.1", 0))
        return int(listen_socket.getsockname()[1])


def executable(path: Path) -> bool:
    return path.exists() and os.access(path, os.X_OK)


def find_capture_tool(explicit_tool: Path | None) -> Path:
    candidates: list[Path] = []
    if explicit_tool is not None:
        candidates.append(explicit_tool)
    if os.environ.get("IREE_TRACY_CAPTURE"):
        candidates.append(Path(os.environ["IREE_TRACY_CAPTURE"]))
    for tool_name in ("iree-tracy-capture", "tracy-capture"):
        path_from_path = shutil.which(tool_name)
        if path_from_path:
            candidates.append(Path(path_from_path))
    for candidate in candidates:
        if executable(candidate):
            return candidate
    raise RuntimeError(
        "Could not find tracy-capture; set IREE_TRACY_CAPTURE, pass "
        "--capture-tool, or put tracy-capture/iree-tracy-capture on PATH"
    )


def terminate(process: subprocess.Popen) -> None:
    if process.poll() is not None:
        return
    process.send_signal(signal.SIGINT)
    try:
        process.wait(timeout=5)
        return
    except subprocess.TimeoutExpired:
        process.terminate()
    try:
        process.wait(timeout=5)
    except subprocess.TimeoutExpired:
        process.kill()


def run_workload(
    command: list[str],
    *,
    env: dict[str, str],
    capture_process: subprocess.Popen,
) -> int:
    workload_process = subprocess.Popen(command, env=env)
    try:
        while True:
            workload_return_code = workload_process.poll()
            if workload_return_code is not None:
                return int(workload_return_code)
            if capture_process.poll() is not None:
                terminate(workload_process)
                raise RuntimeError("tracy-capture exited before the workload")
            time.sleep(0.1)
    except BaseException:
        terminate(workload_process)
        raise


def read_capture_output(capture_output) -> str:
    capture_output.flush()
    capture_output.seek(0)
    return capture_output.read().strip()


def main() -> int:
    args = parse_arguments()
    timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
    trace_name = sanitize_name(args.name or Path(args.command[0]).name)
    output_dir = args.output_dir.resolve()
    output_dir.mkdir(parents=True, exist_ok=True)
    trace_path = output_dir / f"{timestamp}-{trace_name}.tracy"
    trace_port = choose_port(args.port)

    run_env = os.environ.copy()
    run_env["TRACY_NO_EXIT"] = "1"
    run_env["TRACY_ONLY_IPV4"] = "1"
    run_env["TRACY_ONLY_LOCALHOST"] = "1"
    run_env["TRACY_PORT"] = str(trace_port)

    capture_output = None
    capture_process: subprocess.Popen | None = None
    workload_return_code = 1
    try:
        capture_tool = find_capture_tool(args.capture_tool)
        capture_command = [
            str(capture_tool),
            "-o",
            str(trace_path),
            "-f",
            "-a",
            args.address,
            "-p",
            str(trace_port),
        ]
        capture_output = tempfile.TemporaryFile(mode="w+", encoding="utf-8")
        eprint(shlex.join(capture_command))
        capture_process = subprocess.Popen(
            capture_command,
            stdout=capture_output,
            stderr=subprocess.STDOUT,
            text=True,
        )
        time.sleep(0.2)
        if capture_process.poll() is not None:
            raise RuntimeError("tracy-capture exited before the workload")

        eprint(shlex.join(args.command))
        workload_return_code = run_workload(
            args.command,
            env=run_env,
            capture_process=capture_process,
        )

        eprint("waiting for tracy-capture to finish")
        try:
            capture_return_code = int(
                capture_process.wait(timeout=args.capture_exit_timeout)
            )
        except subprocess.TimeoutExpired:
            terminate(capture_process)
            raise RuntimeError("tracy-capture did not finish after the workload exited")
        if capture_return_code != 0:
            raise RuntimeError(
                f"tracy-capture failed with exit code {capture_return_code}"
            )
        if not trace_path.exists():
            raise RuntimeError(f"tracy-capture did not produce {trace_path}")

        eprint(f"trace: {trace_path}")
        return workload_return_code
    except KeyboardInterrupt:
        if capture_process is not None:
            terminate(capture_process)
        raise
    except Exception as exc:
        eprint(str(exc))
        if capture_output is not None:
            output = read_capture_output(capture_output)
            if output:
                eprint("tracy-capture output:")
                sys.stderr.write(output + "\n")
        return workload_return_code if workload_return_code != 0 else 1
    finally:
        if capture_process is not None and capture_process.poll() is None:
            terminate(capture_process)
        if capture_output is not None:
            capture_output.close()


if __name__ == "__main__":
    sys.exit(main())
