#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
"""Snapshot real-Host memory at explicit lifecycle boundaries on macOS.

Use the release native test binary from scripts/agent-scale.py. This rendezvous
pauses the load driver, so its timing results are not performance measurements.
--stacks adds allocator tracing in a separate run; never compare its RSS with
an uninstrumented run. Raw snapshots and command failures are retained.
"""
import argparse
import hashlib
import json
import os
from pathlib import Path
import platform
import re
import subprocess
import time

parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--binary", type=Path, required=True)
parser.add_argument("--agents", type=int, nargs="+", default=[10, 100, 1000])
parser.add_argument("--output", type=Path, default=Path("/tmp/maka-agent-memory"))
parser.add_argument("--stacks", action="store_true")
parser.add_argument("--scenario", choices=["barrier", "flowing"], default="barrier")
parser.add_argument("--waves", type=int, default=5)
parser.add_argument("--mixed", action="store_true")
parser.add_argument("--prompt-bytes", type=int)
parser.add_argument("--delta-bytes", type=int)
parser.add_argument("--deltas", type=int, default=32)
args = parser.parse_args()
if platform.system() != "Darwin" or min(args.agents + [args.deltas, args.waves] + [n for n in (args.prompt_bytes, args.delta_bytes) if n is not None]) < 1:
    parser.error("macOS and positive agent counts are required")
if args.scenario == "barrier" and args.mixed:
    parser.error("--mixed requires --scenario flowing")
if args.scenario == "flowing" and (args.prompt_bytes is not None or args.delta_bytes is not None):
    parser.error("flowing uses fixed light sizes or the deterministic --mixed distribution")
test = "owner::tests::scale::real_host_agent_scale" if args.scenario == "barrier" else "owner::tests::scale::flowing::real_host_agent_memory"
args.output.mkdir(parents=True, exist_ok=True)
report = {
    "machine": platform.platform(),
    "binary": str(args.binary.resolve()),
    "binary_sha256": hashlib.file_digest(args.binary.open("rb"), "sha256").hexdigest(),
    "allocator_tracing": args.stacks,
    "workload": {
        "prompt_bytes": ([1024, 8192, 65536, 262144] if args.mixed else 32) if args.scenario == "flowing" else args.prompt_bytes or 5,
        "delta_bytes": ([16, 256, 2048, 8192] if args.mixed else 6) if args.scenario == "flowing" else args.delta_bytes or 6,
        "deltas": args.deltas, "scenario": args.scenario,
        "waves": args.waves if args.scenario == "flowing" else 1, "mixed": args.mixed,
    },
    "scope": "whole process, including the local HTTP fixture; lifecycle pauses invalidate timing metrics",
    "runs": [],
}


def record():
    (args.output / "report.json").write_text(json.dumps(report, indent=2) + "\n")


for count in args.agents:
    folder = args.output / str(count)
    folder.mkdir(exist_ok=True)
    env = {**os.environ, "MAKA_SCALE_AGENTS": str(count), "MAKA_SCALE_MEMORY_PROFILE": "1"}
    for name, value in (("MAKA_SCALE_PROMPT_BYTES", args.prompt_bytes), ("MAKA_SCALE_DELTA_BYTES", args.delta_bytes), ("MAKA_SCALE_DELTAS", args.deltas)):
        env.pop(name, None)
        if value is not None:
            env[name] = str(value)
    for name in ("MAKA_SCALE_WAVES", "MAKA_SCALE_MIXED", "MallocStackLoggingNoCompact"):
        env.pop(name, None)
    if args.scenario == "flowing":
        env["MAKA_SCALE_WAVES"] = str(args.waves)
        if args.mixed:
            env["MAKA_SCALE_MIXED"] = "1"
    env.pop("MallocStackLogging", None)
    if args.stacks:
        env["MallocStackLogging"] = "1"
    row = {"agents": count, "phases": []}
    report["runs"].append(row)
    with (folder / "stdout.log").open("w") as stdout, (folder / "stderr.log").open("w") as stderr:
        process = subprocess.Popen(
            [str(args.binary.resolve()), test, "--ignored", "--exact", "--nocapture", "--test-threads=1"],
            env=env, stdin=subprocess.PIPE, stdout=stdout, stderr=subprocess.PIPE,
            text=True, bufsize=1,
        )
        try:
            for line in process.stderr:
                stderr.write(line)
                stderr.flush()
                if not line.startswith("MAKA_AGENT_MEMORY "):
                    continue
                phase = line.strip().split()[-1]
                started = time.monotonic()
                sample = {"phase": phase, "commands": []}
                rss = subprocess.check_output(["ps", "-o", "rss=", "-p", str(process.pid)], text=True)
                sample["rss_bytes"] = int(rss.strip()) * 1024
                commands = [
                    ("vmmap", ["vmmap", "-summary", str(process.pid)]),
                    ("heap", ["heap", "-s", "--noContent", str(process.pid)]),
                ]
                if args.stacks and phase.endswith(("all_active", "all_admitted", "output_settled", "dropped")):
                    commands.append(("stacks", ["malloc_history", str(process.pid), "-callTree", "-invert", "-ignoreThreads", "-noContent", "-consolidateAllBySymbol"]))
                for name, command in commands:
                    destination = folder / f"{phase}-{name}.txt"
                    with destination.open("w") as output:
                        remaining = 40 - (time.monotonic() - started)
                        if remaining <= 0:
                            sample["commands"].append({"tool": name, "skipped": "checkpoint time budget exhausted"})
                            continue
                        timeout = min(20, remaining)
                        try:
                            result = subprocess.run(command, stdout=output, stderr=subprocess.STDOUT, timeout=timeout)
                            status = {"tool": name, "exit_code": result.returncode}
                        except subprocess.TimeoutExpired:
                            status = {"tool": name, "timeout_seconds": timeout}
                    sample["commands"].append(status)
                heap_text = (folder / f"{phase}-heap.txt").read_text()
                allocated = re.search(r"All zones: (\d+) nodes \((\d+) bytes\)", heap_text)
                if allocated:
                    sample["malloc_live_blocks"] = int(allocated[1])
                    sample["malloc_live_bytes"] = int(allocated[2])
                footprint = re.search(r"Physical footprint: *([^\n]+)", heap_text)
                if footprint:
                    sample["physical_footprint"] = footprint[1]
                sample["checkpoint_seconds"] = time.monotonic() - started
                row["phases"].append(sample)
                record()
                print(json.dumps({"agents": count, **sample}), flush=True)
                process.stdin.write("x")
                process.stdin.flush()
            row["exit_code"] = process.wait(timeout=30)
        finally:
            if process.poll() is None:
                process.terminate()
                process.wait(timeout=10)
            process.stdin.close()
    record()
    if not row["phases"]:
        raise SystemExit(f"no checkpoints; rebuild the test binary: {folder}")
    if row["exit_code"]:
        raise SystemExit(f"profiled load failed (inspect workload and checkpoint diagnostics): {folder}")
    if any(command.get("exit_code") != 0 for phase in row["phases"] for command in phase["commands"]):
        raise SystemExit(f"incomplete profiler evidence: {folder}")
print(f"Evidence: {args.output / 'report.json'}")
