"""Camera capture utility for HP w300 on Arduino UNO Q MPU.

Captures frames from the USB webcam at configurable resolution.
Default: 640x480 MJPG (suitable for Edge Impulse ML inference).

Usage:
    python camera_capture.py                    # single frame to /tmp/capture.jpg
    python camera_capture.py --count 5          # 5 frames to /tmp/captures/
    python camera_capture.py --width 1920 --height 1080  # full HD
    python camera_capture.py --backlight 120              # boost backlight compensation
    python camera_capture.py --brightness 10              # adjust brightness
"""

import argparse
import cv2
import glob
import os
import subprocess
import time


def find_camera(name="w300"):
    """Find camera index by name using v4l2-ctl. Returns index or None."""
    try:
        result = subprocess.run(
            ["v4l2-ctl", "--list-devices"],
            capture_output=True, text=True, timeout=5,
        )
        lines = result.stdout.splitlines()
        for i, line in enumerate(lines):
            if name.lower() in line.lower():
                # Next line(s) have /dev/videoN paths — take the first
                for dev_line in lines[i + 1 :]:
                    dev_line = dev_line.strip()
                    if not dev_line or not dev_line.startswith("/dev/video"):
                        break
                    index = int(dev_line.replace("/dev/video", ""))
                    return index
    except (subprocess.TimeoutExpired, FileNotFoundError, ValueError):
        pass
    return None


def capture(width=640, height=480, count=1, output_dir="/tmp/captures",
            backlight=None, brightness=None):
    camera_index = find_camera("w300")
    if camera_index is None:
        print("ERROR: Could not find HP w300 camera. Is it plugged in?")
        return False
    print(f"Found camera at /dev/video{camera_index}")

    cap = cv2.VideoCapture(camera_index)
    cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"MJPG"))
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
    if backlight is not None:
        cap.set(cv2.CAP_PROP_BACKLIGHT, backlight)
    if brightness is not None:
        cap.set(cv2.CAP_PROP_BRIGHTNESS, brightness)

    if not cap.isOpened():
        print("ERROR: Could not open camera")
        return False

    time.sleep(1)  # auto-exposure settle

    os.makedirs(output_dir, exist_ok=True)

    for i in range(count):
        ret, frame = cap.read()
        if ret:
            if count == 1:
                path = os.path.join(output_dir, "capture.jpg")
            else:
                path = os.path.join(output_dir, f"frame_{i:03d}.jpg")
            cv2.imwrite(path, frame)
            h, w = frame.shape[:2]
            print(f"Frame {i}: {w}x{h} -> {path}")
        else:
            print(f"Frame {i}: ERROR reading frame")
        if i < count - 1:
            time.sleep(0.5)

    actual_w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    actual_h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    print(f"\nCamera: /dev/video{camera_index}, {actual_w}x{actual_h}, {cap.get(cv2.CAP_PROP_FPS):.0f} fps")

    cap.release()
    return True


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Capture frames from HP w300 webcam")
    parser.add_argument("--width", type=int, default=640)
    parser.add_argument("--height", type=int, default=480)
    parser.add_argument("--count", type=int, default=1)
    parser.add_argument("--output-dir", default="/tmp/captures")
    parser.add_argument("--backlight", type=int, default=None, help="Backlight compensation (0-160)")
    parser.add_argument("--brightness", type=int, default=None, help="Brightness (-64 to 64)")
    args = parser.parse_args()

    capture(args.width, args.height, args.count, args.output_dir,
            args.backlight, args.brightness)
