#!/usr/bin/env bash
# ============================================================
# Velocity-OS — Ingress Box: Air-Gap Transfer Agent
# Runs on a LAN-connected node (Raspberry Pi / VM).
# Polls ECR every 5 minutes for new signed images.
# Verifies cosign signature. Transfers to air-gapped workstation.
# Triggers K3s rolling restart on new image.
#
# Install as systemd service:
#   sudo cp poll_and_transfer.service /etc/systemd/system/
#   sudo systemctl enable --now poll_and_transfer
# ============================================================
set -euo pipefail

# ── Configuration ────────────────────────────────────────────
AWS_REGION="${AWS_REGION:-ap-south-1}"
AWS_ACCOUNT_ID="${AWS_ACCOUNT_ID:?Must set AWS_ACCOUNT_ID}"
ECR_REGISTRY="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"
REGISTRY_PREFIX="velocity-os"
SERVICES=("core" "webos" "media-engine" "agents")

# Air-gapped workstation (LAN only — no internet)
WORKSTATION_IP="${WORKSTATION_IP:-192.168.1.100}"
WORKSTATION_USER="${WORKSTATION_USER:-ubuntu}"
WORKSTATION_SSH_KEY="${WORKSTATION_SSH_KEY:-/home/ingress/.ssh/velocity_workstation_ed25519}"

# State file: tracks last-transferred digest per service
STATE_DIR="/var/lib/velocity-ingress"
mkdir -p "${STATE_DIR}"

# Temp dir for image tarballs
TRANSFER_DIR="/tmp/velocity-transfer"
mkdir -p "${TRANSFER_DIR}"

# ── Functions ─────────────────────────────────────────────────
log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*"; }

get_latest_digest() {
  local repo="${REGISTRY_PREFIX}/$1"
  aws ecr describe-images \
    --repository-name "${repo}" \
    --image-ids imageTag=latest \
    --region "${AWS_REGION}" \
    --query 'imageDetails[0].imageDigest' \
    --output text 2>/dev/null || echo "NONE"
}

transfer_image() {
  local svc="$1"
  local digest="$2"
  local full_image="${ECR_REGISTRY}/${REGISTRY_PREFIX}/${svc}@${digest}"
  local tar_file="${TRANSFER_DIR}/${svc}.tar"

  log "  [${svc}] Pulling from ECR..."
  docker pull "${ECR_REGISTRY}/${REGISTRY_PREFIX}/${svc}:latest"

  log "  [${svc}] Verifying cosign signature..."
  cosign verify \
    --certificate-identity-regexp ".*" \
    --certificate-oidc-issuer-regexp ".*" \
    "${full_image}" || {
    log "  [${svc}] ERROR: Signature verification FAILED. Refusing transfer."
    return 1
  }

  log "  [${svc}] Saving image to tarball..."
  docker save "${ECR_REGISTRY}/${REGISTRY_PREFIX}/${svc}:latest" \
    -o "${tar_file}"

  log "  [${svc}] Transferring to workstation via SCP..."
  scp -i "${WORKSTATION_SSH_KEY}" \
    -o StrictHostKeyChecking=yes \
    "${tar_file}" \
    "${WORKSTATION_USER}@${WORKSTATION_IP}:/tmp/${svc}.tar"

  log "  [${svc}] Importing into K3s containerd + rolling restart..."
  ssh -i "${WORKSTATION_SSH_KEY}" \
    -o StrictHostKeyChecking=yes \
    "${WORKSTATION_USER}@${WORKSTATION_IP}" \
    "sudo k3s ctr images import /tmp/${svc}.tar && \
     sudo kubectl rollout restart deployment/${svc} -n velocity-os && \
     rm /tmp/${svc}.tar"

  # Record transferred digest
  echo "${digest}" > "${STATE_DIR}/${svc}.last_digest"
  log "  [${svc}] ✓ Transfer complete. Digest: ${digest}"
  rm -f "${tar_file}"
}

# ── Main poll loop ────────────────────────────────────────────
log "=== Velocity-OS Ingress Box polling ECR ==="

# Login to ECR (token expires every 12h; cron re-runs this)
aws ecr get-login-password --region "${AWS_REGION}" | \
  docker login --username AWS --password-stdin "${ECR_REGISTRY}"

for svc in "${SERVICES[@]}"; do
  log "[${svc}] Checking for updates..."

  CURRENT_DIGEST=$(get_latest_digest "${svc}")
  LAST_DIGEST=$(cat "${STATE_DIR}/${svc}.last_digest" 2>/dev/null || echo "NONE")

  if [[ "${CURRENT_DIGEST}" == "NONE" ]]; then
    log "  [${svc}] No image found in ECR. Skipping."
    continue
  fi

  if [[ "${CURRENT_DIGEST}" == "${LAST_DIGEST}" ]]; then
    log "  [${svc}] Up to date. No transfer needed."
    continue
  fi

  log "  [${svc}] New digest detected: ${CURRENT_DIGEST}"
  transfer_image "${svc}" "${CURRENT_DIGEST}" || \
    log "  [${svc}] Transfer FAILED. Will retry next cycle."
done

log "=== Poll cycle complete ==="
