#!/bin/bash
# moon-track.sh — nightly: detect the moon in each east night frame, crop a
# fixed-size box around it, stitch the cropped sequence into an mp4 that holds
# the moon roughly centred while clouds, halo and stars drift past.
#
# Run once per day from systemd around 02:00, after the night the moon was up.
# Processes YESTERDAY's frames by default; pass YYYY-MM-DD to back-fill.
#
# Output: $MOVIES_DIR/<cam>/moon-track/YYYY/YYYY-MM-DD-moon-track.mp4

set -euo pipefail

SCRIPT_DIR="$(dirname "$(realpath "$0")")"
source "$SCRIPT_DIR/sky-cam.conf"
export TZ="$TIMEZONE"

CAM_NAME="${1:-${SUNRISE_CAM:-east}}"
DATE_ARG="${2:-}"
if [ -n "$DATE_ARG" ]; then
    target_date=$(date --date="$DATE_ARG" +%Y-%m-%d)
else
    target_date=$(date --date="yesterday" +%Y-%m-%d)
fi

if [ "${MOON_TRACK_ENABLED:-true}" != "true" ]; then
    echo "MOON_TRACK_ENABLED=false — skipping"
    exit 0
fi

image_dir="$BASE_DIR/$CAM_NAME/$target_date"
if [ ! -d "$image_dir" ]; then
    echo "no images for $CAM_NAME on $target_date — skipping"
    exit 0
fi

year="${target_date:0:4}"
out_dir="$MOVIES_DIR/$CAM_NAME/moon-track/$year"
mkdir -p "$out_dir"
final="$out_dir/${target_date}-moon-track.mp4"

# Crop size around the detected moon, in source pixels.  At 4K with a ~38 px
# moon, 480 px gives a comfortable surround with halo and any clouds visible.
CROP_PX="${MOON_TRACK_CROP_PX:-480}"
FPS="${MOON_TRACK_FPS:-12}"
CRF="${MOON_TRACK_CRF:-24}"

work_dir=$(mktemp -d)
trap 'rm -rf "$work_dir"' EXIT

export SCRIPT_DIR
echo "Scanning $image_dir for night frames with the moon visible..."
python3 - "$image_dir" "$work_dir" "$CROP_PX" <<'PY'
import os, sys
sys.path.insert(0, os.environ['SCRIPT_DIR'])
from PIL import Image
from moon_detect import detect_moon

image_dir = sys.argv[1]
work_dir  = sys.argv[2]
crop_px   = int(sys.argv[3])
half = crop_px // 2

frames = sorted(f for f in os.listdir(image_dir) if f.endswith('.jpg'))
n = len(frames)
written = 0
for i, name in enumerate(frames):
    p = os.path.join(image_dir, name)
    det = detect_moon(p)
    if det is None:
        continue
    cx, cy = det.centroid_xy
    im = Image.open(p)
    w, h = im.size
    left = max(0, min(int(cx - half), w - crop_px))
    top  = max(0, min(int(cy - half), h - crop_px))
    crop = im.crop((left, top, left + crop_px, top + crop_px))
    out = os.path.join(work_dir, f'{written:06d}.jpg')
    crop.save(out, quality=88)
    written += 1
    if (i + 1) % 200 == 0 or i + 1 == n:
        print(f'  scanned {i + 1}/{n} frames, kept {written}', flush=True)
print(f'moon-detected frames: {written}')
PY

count=$(find "$work_dir" -maxdepth 1 -name '*.jpg' | wc -l)
if [ "$count" -lt 10 ]; then
    echo "only $count moon-visible frames on $target_date — skipping video build"
    exit 0
fi

echo "encoding $count frames into $final ..."
ffmpeg -loglevel warning -y \
    -framerate "$FPS" \
    -i "$work_dir/%06d.jpg" \
    -c:v libx264 -pix_fmt yuv420p -preset "${ENCODE_PRESET:-slow}" \
    -crf "$CRF" \
    "$final"

echo "moon-track: $final ($(du -h "$final" | cut -f1))"

# Retention sweep
RETENTION="${MOON_TRACK_RETENTION_DAYS:-90}"
if [ "$RETENTION" -gt 0 ]; then
    find "$MOVIES_DIR/$CAM_NAME/moon-track" -type f -name '*-moon-track.mp4' \
         -mtime +"$RETENTION" -delete 2>/dev/null || true
fi
