#!/usr/bin/env python3
"""
perfctl - unprivileged client for elphel-perfd (127.0.0.1:48890).

    perfctl status                     one-line daemon/clock status
    perfctl ping                       probe (exit 0 = daemon installed)
    perfctl hold <measure|max> [cpu=KHZ] [gpu=MHZ]
                                       hold until Ctrl-C (overrides optional)
    perfctl hold <measure|max> [cpu=KHZ] [gpu=MHZ] -- CMD [ARGS...]
                                       hold for the duration of CMD
The hold is tied to this process's connection: if perfctl dies, the daemon
releases automatically. cpu=/gpu= override the daemon's 'measure' lock
defaults (bounds-checked server-side) - for calibration without
reconfiguration. By Claude on 07/17/2026.
"""
import os
import signal
import socket
import subprocess
import sys

PORT = int(os.environ.get("PERFD_PORT", "48890"))


def connect():
    s = socket.create_connection(("127.0.0.1", PORT), timeout=2.0)
    return s, s.makefile("rw", encoding="utf-8")


def ask(f, line):
    f.write(line + "\n")
    f.flush()
    return f.readline().strip()


def main():
    args = sys.argv[1:]
    if not args or args[0] not in ("status", "ping", "hold"):
        print(__doc__.strip())
        return 2
    try:
        s, f = connect()
    except OSError as e:
        print("perfctl: elphel-perfd not reachable on 127.0.0.1:%d (%s)" % (PORT, e))
        print("perfctl: install once with:  sudo <imagej-elphel>/perfd/install.sh")
        return 3
    if args[0] == "ping":
        print(ask(f, "PING"))
        return 0
    if args[0] == "status":
        print(ask(f, "STATUS"))
        return 0
    # hold [cpu=KHZ] [gpu=MHZ] [-- CMD...]
    if len(args) < 2 or args[1] not in ("measure", "max"):
        print("perfctl: hold needs a profile: measure | max")
        return 2
    overrides = []
    rest = args[2:]
    while rest and ("=" in rest[0]) and (rest[0] != "--"):
        overrides.append(rest.pop(0))
    reply = ask(f, " ".join(["HOLD", args[1]] + overrides))
    print("perfctl: " + reply)
    if not reply.startswith("OK"):
        return 1
    if rest and rest[0] == "--":
        rc = subprocess.call(rest[1:])
        ask(f, "RELEASE")
        return rc
    print("perfctl: holding '%s' until Ctrl-C ..." % args[1])
    try:
        signal.pause()
    except KeyboardInterrupt:
        pass
    ask(f, "RELEASE")
    print("perfctl: released")
    return 0


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