#!/usr/bin/env python3
# rikkiti-msg — send a command, or run a query, against the Rikkiti compositor IPC
# (the socket at $RIKKITISOCK; i3-ipc framing). Like swaymsg.
#
#   rikkiti-msg output HDMI-A-1 scale 1.5     # run a compositor command
#   rikkiti-msg workspace 3
#   rikkiti-msg get-outputs                   # query → prints the JSON reply
#   rikkiti-msg get-workspaces
import socket, struct, sys, os, time

QUERIES = {"get-workspaces": 1, "get-windows": 2, "get-outputs": 3}

def main():
    sock = os.environ.get("RIKKITISOCK")
    if not sock:
        sys.exit("rikkiti-msg: RIKKITISOCK not set (run inside a Rikkiti session)")
    args = sys.argv[1:]
    if not args:
        sys.exit("usage: rikkiti-msg <command…> | rikkiti-msg get-outputs|get-workspaces|get-windows")
    if args[0] in QUERIES:
        typ, payload = QUERIES[args[0]], b""
    else:
        typ, payload = 0, " ".join(args).encode()  # type 0 = COMMAND
    try:
        s = socket.socket(socket.AF_UNIX); s.connect(sock)
    except OSError as e:
        sys.exit(f"rikkiti-msg: cannot connect to {sock}: {e}")
    s.send(b"i3-ipc" + struct.pack("=II", len(payload), typ) + payload)
    if True:  # ALWAYS read the reply — closing instantly can race the dispatch
        time.sleep(0.2)
        hdr = b""
        while len(hdr) < 14:
            c = s.recv(14 - len(hdr))
            if not c: break
            hdr += c
        if len(hdr) >= 14:
            ln = struct.unpack("=I", hdr[6:10])[0]
            data = b""
            while len(data) < ln:
                c = s.recv(ln - len(data))
                if not c: break
                data += c
            sys.stdout.write(data.decode("utf-8", "replace"))
            if not data.endswith(b"\n"):
                sys.stdout.write("\n")

if __name__ == "__main__":
    main()
