#!/usr/bin/env bash

set -euo pipefail

ARCHIVE="${1:-}"
IMAGE="${2:-}"
ENV_FILE="${3:-}"
HOST_PORT="${4:-9135}"
CONTAINER_NAME="cozsweet-frontend-domestic-test"
INTERNAL_PORT="3000"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
SHARED_ROOT="$SERVICE_ROOT/shared"
RELEASE_ROOT="$SERVICE_ROOT/releases/docker"

if [ -z "$ARCHIVE" ] || [ -z "$IMAGE" ] || [ -z "$ENV_FILE" ]; then
  echo "Usage: $0 <image-archive> <image> <env-file> [host-port]" >&2
  exit 64
fi
if [ "$HOST_PORT" != "9135" ]; then
  echo "Domestic frontend test must use isolated host port 9135" >&2
  exit 64
fi
case "$ENV_FILE" in
  "$SHARED_ROOT"/*) ;;
  *)
    echo "Environment file must be stored under $SHARED_ROOT" >&2
    exit 64
    ;;
esac
if [ ! -s "$ARCHIVE" ] || [ ! -s "$ENV_FILE" ]; then
  echo "Image archive or environment file is missing" >&2
  exit 66
fi

mkdir -p "$RELEASE_ROOT"
chmod 700 "$SHARED_ROOT"
gzip -dc "$ARCHIVE" | docker load >/dev/null
docker image inspect "$IMAGE" >/dev/null

old_image_id=""
old_image_ref=""
if docker container inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
  old_image_id="$(docker inspect -f '{{.Image}}' "$CONTAINER_NAME")"
  old_image_ref="$(docker inspect -f '{{.Config.Image}}' "$CONTAINER_NAME")"
elif ss -ltnH "sport = :$HOST_PORT" 2>/dev/null | grep -q .; then
  echo "Host port $HOST_PORT is already used by another service" >&2
  exit 69
fi

run_container() {
  local image_ref="$1"
  docker run -d \
    --name "$CONTAINER_NAME" \
    --restart unless-stopped \
    -p "127.0.0.1:$HOST_PORT:$INTERNAL_PORT" \
    --env-file "$ENV_FILE" \
    -e "PORT=$INTERNAL_PORT" \
    "$image_ref" >/dev/null
}

wait_healthy() {
  local deadline=$((SECONDS + 180))
  while [ "$SECONDS" -le "$deadline" ]; do
    state="$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$CONTAINER_NAME" 2>/dev/null || true)"
    status="$(curl -sS -o /dev/null -w '%{http_code}' "http://127.0.0.1:$HOST_PORT/" 2>/dev/null || true)"
    if [[ "$status" =~ ^(200|204|301|302|303|307|308)$ ]] && { [ "$state" = "healthy" ] || [ "$state" = "running" ]; }; then
      return 0
    fi
    sleep 2
  done
  return 1
}

docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
deployment_ok="1"
if ! run_container "$IMAGE"; then
  deployment_ok="0"
elif ! wait_healthy; then
  deployment_ok="0"
fi

if [ "$deployment_ok" != "1" ]; then
  docker logs --tail 120 "$CONTAINER_NAME" >&2 || true
  docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
  if [ -n "$old_image_id" ] && docker image inspect "$old_image_id" >/dev/null 2>&1; then
    echo "New container failed health checks; restoring previous image" >&2
    run_container "$old_image_id"
    wait_healthy || true
  fi
  exit 1
fi

created_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
image_id="$(docker image inspect "$IMAGE" -f '{{.Id}}')"
record="{\"createdAt\":\"$created_at\",\"environment\":\"domestic-test\",\"image\":\"$IMAGE\",\"imageId\":\"$image_id\",\"container\":\"$CONTAINER_NAME\",\"hostPort\":$HOST_PORT}"
if [ -f "$RELEASE_ROOT/current.json" ]; then
  cp "$RELEASE_ROOT/current.json" "$RELEASE_ROOT/previous.json"
fi
printf '%s\n' "$record" > "$RELEASE_ROOT/current.json"
printf '%s\n' "$record" >> "$RELEASE_ROOT/releases.jsonl"

echo "Domestic frontend test is healthy"
echo "container=$CONTAINER_NAME"
echo "host_port=$HOST_PORT"
echo "image=$IMAGE"
if [ -n "$old_image_ref" ]; then
  echo "previous_image=$old_image_ref"
fi
