#!/usr/bin/env python3
"""Copy one explicitly selected fisheye image from the onboard image API to /data.

This program is intended to run in a pod with the payload volume mounted at /data.
It never chooses an image by ordering or timestamp: set DPHI_FISHEYE_IMAGE to a name
returned by the list endpoint.
"""

import io
import json
import os
import sys
import urllib.error
import urllib.request
import zipfile
from pathlib import Path

API_BASE = os.environ.get("DPHI_FISHEYE_API_BASE", "http://satellite-telemetry.dphi-tm/api/images").rstrip("/")
IMAGE_NAME = os.environ.get("DPHI_FISHEYE_IMAGE")
OUTPUT_PATH = Path(os.environ.get("DPHI_FISHEYE_OUTPUT", "/data/selected-fisheye.png"))
TIMEOUT_SECONDS = float(os.environ.get("DPHI_HTTP_TIMEOUT", "15"))


def request(url, data=None):
    headers = {"Content-Type": "application/json"} if data is not None else {}
    request = urllib.request.Request(url, data=data, headers=headers)
    try:
        with urllib.request.urlopen(request, timeout=TIMEOUT_SECONDS) as response:
            return response.read()
    except (urllib.error.HTTPError, urllib.error.URLError, TimeoutError) as error:
        raise RuntimeError(f"onboard image API request failed for {url}: {error}") from error


def list_images():
    payload = json.loads(request(f"{API_BASE}/list"))
    if not isinstance(payload, (list, dict)):
        raise RuntimeError("onboard image API returned an unexpected list response")
    return payload


def fetch_image(image_name):
    archive = request(API_BASE, json.dumps({"images": [image_name]}).encode())
    try:
        with zipfile.ZipFile(io.BytesIO(archive)) as zipped:
            candidates = [name for name in zipped.namelist() if not name.endswith("/")]
            if image_name not in candidates:
                raise RuntimeError(f"requested image {image_name!r} was not returned; got {candidates!r}")
            return zipped.read(image_name)
    except zipfile.BadZipFile as error:
        raise RuntimeError("onboard image API did not return a ZIP archive") from error


def main():
    available = list_images()
    print("Available image list:")
    print(json.dumps(available, indent=2, sort_keys=True))
    if not IMAGE_NAME:
        raise RuntimeError("set DPHI_FISHEYE_IMAGE to one exact name from the list above")
    image = fetch_image(IMAGE_NAME)
    OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True)
    OUTPUT_PATH.write_bytes(image)
    print(f"Wrote {len(image)} bytes to {OUTPUT_PATH}")


if __name__ == "__main__":
    try:
        main()
    except RuntimeError as error:
        print(f"ERROR: {error}", file=sys.stderr)
        raise SystemExit(1)
