#!/usr/bin/env python3
"""
take_photo.py (Option A) - Capture ONE frame from teleimager ZMQ JPEG stream and save it.

Why:
- teleimager.image_server owns the RealSense device, so /dev/video0 is BUSY.
- Instead of opening the camera, we subscribe to teleimager's ZMQ JPEG stream and save 1 frame.

Env:
  TELEIMAGER_HOST   default: 127.0.0.1
  ZMQ_PORT          default: 55555
  PHOTOS_DIR        default: ./photos
  PHOTO_PREFIX      default: photo
  PHOTO_EXT         default: jpg
  FRAME_TIMEOUT_S   default: 3.0

Output:
- prints saved absolute path as LAST LINE (so sanad_voice.py can log it)
"""

import os
import sys
import time
from pathlib import Path
from Logger import Logs

sanad_logger = Logs()
sanad_logger.LogEngine("G1_Logs", "take_photo") 


def eprint(*a):
    print(*a, file=sys.stderr)

def next_name(out_dir: Path, prefix: str, ext: str) -> Path:
    """photo.jpg, photo(1).jpg, photo(2).jpg ..."""
    base = out_dir / f"{prefix}.{ext}"
    if not base.exists():
        return base
    i = 1
    while True:
        p = out_dir / f"{prefix}({i}).{ext}"
        if not p.exists():
            return p
        i += 1

def recv_one_jpeg_zmq(host: str, port: int, timeout_s: float) -> bytes:
    import zmq  # requires pyzmq in teleimager env

    ctx = zmq.Context.instance()
    sub = ctx.socket(zmq.SUB)
    sub.setsockopt(zmq.RCVHWM, 1)      # keep only latest
    sub.setsockopt(zmq.LINGER, 0)
    sub.setsockopt_string(zmq.SUBSCRIBE, "")
    sub.connect(f"tcp://{host}:{port}")

    poller = zmq.Poller()
    poller.register(sub, zmq.POLLIN)

    deadline = time.monotonic() + timeout_s
    last = b""

    try:
        # drain quickly to newest
        while time.monotonic() < deadline:
            remaining_ms = max(1, int((deadline - time.monotonic()) * 1000))
            events = dict(poller.poll(timeout=min(200, remaining_ms)))
            if sub in events:
                msg = sub.recv()
                if msg:
                    last = msg  # keep newest
                    # if we got something, we can return immediately
                    return last
        raise TimeoutError("No JPEG frame received from ZMQ in time.")
    finally:
        try:
            sub.close()
        except Exception:
            pass

def main():
    host = os.getenv("TELEIMAGER_HOST", "127.0.0.1")
    port = int(os.getenv("ZMQ_PORT", os.getenv("TELEIMAGER_ZMQ_PORT", "55555")))
    out_dir = Path(os.getenv("PHOTOS_DIR", "./photos")).expanduser().resolve()
    prefix = os.getenv("PHOTO_PREFIX", "photo").strip() or "photo"
    ext = os.getenv("PHOTO_EXT", "jpg").strip().lstrip(".") or "jpg"
    timeout_s = float(os.getenv("FRAME_TIMEOUT_S", "3.0"))

    out_dir.mkdir(parents=True, exist_ok=True)

    try:
        jpg = recv_one_jpeg_zmq(host, port, timeout_s)
    except Exception as e:
        eprint("[ERR] take_photo.py failed")
        eprint(f"[zmq] {e}")
        return 4

    # (اختياري) تحقق أنه JPEG فعلاً
    if len(jpg) < 50:
        eprint("[ERR] take_photo.py failed")
        eprint("[zmq] Received too-small frame.")
        return 5

    out_path = next_name(out_dir, prefix, ext)
    try:
        out_path.write_bytes(jpg)
    except Exception as e:
        eprint("[ERR] take_photo.py failed")
        eprint(f"[fs] Could not write file: {e}")
        return 6

    # IMPORTANT: last line should be path only
    sanad_logger.print_and_log(str(out_path))
    return 0

if __name__ == "__main__":
    raise SystemExit(main())
