#!/usr/bin/env bash
set -euo pipefail

readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
readonly REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
readonly STACK_DIR="$REPO_ROOT/infra/aws-tokyo"
readonly RELEASE_DIR="$STACK_DIR/.terraform-build"
readonly DEFAULT_KNOWN_HOSTS_PATH="$RELEASE_DIR/known_hosts"
readonly REMOTE_CADDYFILE_PATH='/etc/caddy/Caddyfile'

source "$SCRIPT_DIR/_lib.sh"

usage() {
  cat <<'EOF' >&2
Usage:
  scripts/release/sync-caddyfile.sh

Environment variables:
  AGENTTEAM_INSTANCE_ID           (optional; when set, prefer syncing via SSM over SSH)
  AGENTTEAM_AWS_REGION            (default: ap-northeast-1; used for SSM)
  AGENTTEAM_PUBLIC_IP             (required unless Terraform state exists)
  AGENTTEAM_SSH_PRIVATE_KEY_PATH  (default: ~/.ssh/id_rsa)
  AGENTTEAM_SSH_PORT              (default: 2222)
  AGENTTEAM_SSH_USER              (default: ubuntu)
  AGENTTEAM_SSH_KNOWN_HOSTS_PATH  (default: infra/aws-tokyo/.terraform-build/known_hosts)
  AGENTTEAM_CADDYFILE_PATH        (optional; use a local file as Caddyfile source)
  AGENTTEAM_CADDYFILE_CONTENT_B64 (optional; base64-encoded Caddyfile content; preferred when invoked by Terraform)

This script uploads a Caddyfile to the EC2 instance:
  /etc/caddy/Caddyfile

Then validates it and reloads the caddy systemd service.

If no Caddyfile source is provided, it will attempt to read Terraform output:
  terraform -chdir=infra/aws-tokyo output -raw rendered_caddyfile
EOF
}

decode_base64() {
  if base64 -d </dev/null >/dev/null 2>&1; then
    base64 -d
    return 0
  fi
  if base64 -D </dev/null >/dev/null 2>&1; then
    base64 -D
    return 0
  fi
  echo "unsupported base64 implementation (needs -d or -D)" >&2
  return 1
}

instance_id="${AGENTTEAM_INSTANCE_ID:-}"
aws_region="${AGENTTEAM_AWS_REGION:-ap-northeast-1}"

caddyfile_path="${AGENTTEAM_CADDYFILE_PATH:-}"
caddyfile_content_b64="${AGENTTEAM_CADDYFILE_CONTENT_B64:-}"

require_command bash

mkdir -p "$RELEASE_DIR"

tmp_caddyfile_path="$RELEASE_DIR/Caddyfile.$$.tmp"
cleanup() {
  rm -f "$tmp_caddyfile_path"
}
trap cleanup EXIT

if [[ -n "$caddyfile_content_b64" ]]; then
  require_command base64
  printf '%s' "$caddyfile_content_b64" | decode_base64 >"$tmp_caddyfile_path"
elif [[ -n "$caddyfile_path" ]]; then
  if [[ ! -f "$caddyfile_path" ]]; then
    echo "Caddyfile not found: $caddyfile_path" >&2
    exit 1
  fi
  cp -f "$caddyfile_path" "$tmp_caddyfile_path"
else
  if ! command -v terraform >/dev/null 2>&1; then
    usage
    echo "" >&2
    echo "missing Caddyfile source: set AGENTTEAM_CADDYFILE_PATH or AGENTTEAM_CADDYFILE_CONTENT_B64, or install terraform with local state." >&2
    exit 1
  fi

  if ! terraform -chdir="$STACK_DIR" output -raw rendered_caddyfile >"$tmp_caddyfile_path"; then
    usage
    echo "" >&2
    echo "failed to read Terraform output rendered_caddyfile; set AGENTTEAM_CADDYFILE_PATH or AGENTTEAM_CADDYFILE_CONTENT_B64 instead." >&2
    exit 1
  fi
fi

if [[ -n "$instance_id" ]]; then
  require_command aws
  require_command base64
  require_command tr

  if [[ -z "$caddyfile_content_b64" ]]; then
    caddyfile_content_b64="$(base64 <"$tmp_caddyfile_path" | tr -d '\n')"
  fi

  ssm_commands=(
    "set -eu"
    "umask 022"
    "install -d -m 0755 /etc/caddy"
    "printf '%s' '$caddyfile_content_b64' | base64 -d > '$REMOTE_CADDYFILE_PATH.tmp'"
    "caddy validate --config '$REMOTE_CADDYFILE_PATH.tmp'"
    "mv -f '$REMOTE_CADDYFILE_PATH.tmp' '$REMOTE_CADDYFILE_PATH'"
    "systemctl reload caddy || systemctl restart caddy"
  )

  parameters="{\"commands\":[\"${ssm_commands[0]}\""
  for ((i = 1; i < ${#ssm_commands[@]}; i++)); do
    parameters+=",\"${ssm_commands[$i]}\""
  done
  parameters+="]}"

  command_id="$(
    aws ssm send-command \
      --region "$aws_region" \
      --instance-ids "$instance_id" \
      --document-name AWS-RunShellScript \
      --comment 'agentteam sync caddyfile' \
      --parameters "$parameters" \
      --query 'Command.CommandId' \
      --output text
  )"

  for attempt in $(seq 1 60); do
    status="$(aws ssm get-command-invocation --region "$aws_region" --command-id "$command_id" --instance-id "$instance_id" --query 'Status' --output text 2>/dev/null || true)"
    case "$status" in
    Success)
      echo "synced Caddyfile to $instance_id:$REMOTE_CADDYFILE_PATH via SSM ($aws_region)"
      exit 0
      ;;
    Failed | Cancelled | TimedOut)
      break
      ;;
    Pending | InProgress | Delayed | "")
      sleep 2
      ;;
    *)
      sleep 2
      ;;
    esac
  done

  invocation="$(aws ssm get-command-invocation --region "$aws_region" --command-id "$command_id" --instance-id "$instance_id" --output json || true)"
  echo "failed to sync caddyfile via SSM (status: ${status:-unknown})" >&2
  if [[ -n "$invocation" ]]; then
    echo "" >&2
    echo "$invocation" >&2
  fi
  exit 1
fi

public_ip="$(agentteam_resolve_public_ip "$STACK_DIR")"
if [[ -z "$public_ip" ]]; then
  usage
  echo "" >&2
  echo "AGENTTEAM_PUBLIC_IP is required (or run with Terraform + local state for infra/aws-tokyo)." >&2
  exit 1
fi

ssh_private_key_path="${AGENTTEAM_SSH_PRIVATE_KEY_PATH:-$HOME/.ssh/id_rsa}"
ssh_port="${AGENTTEAM_SSH_PORT:-2222}"
ssh_user="${AGENTTEAM_SSH_USER:-ubuntu}"
known_hosts_path="${AGENTTEAM_SSH_KNOWN_HOSTS_PATH:-$DEFAULT_KNOWN_HOSTS_PATH}"

require_command ssh

if [[ ! -f "$ssh_private_key_path" ]]; then
  echo "SSH private key not found: $ssh_private_key_path" >&2
  exit 1
fi

agentteam_prepare_known_hosts "$known_hosts_path"
agentteam_build_ssh_options "$ssh_private_key_path" "$ssh_port" "$known_hosts_path"
agentteam_wait_for_ssh "$ssh_user" "$public_ip" "$ssh_port"

remote_commands=(
  "sudo -n bash -c 'set -euo pipefail; umask 022; install -d -m 0755 /etc/caddy; cat > \"$REMOTE_CADDYFILE_PATH.tmp\"; caddy validate --config \"$REMOTE_CADDYFILE_PATH.tmp\"; mv -f \"$REMOTE_CADDYFILE_PATH.tmp\" \"$REMOTE_CADDYFILE_PATH\"'"
  "sudo -n systemctl reload caddy || sudo -n systemctl restart caddy"
)

agentteam_ssh "$ssh_user@$public_ip" "$(printf '%s && ' "${remote_commands[@]}") true" <"$tmp_caddyfile_path"

echo "synced Caddyfile to $ssh_user@$public_ip:$ssh_port:$REMOTE_CADDYFILE_PATH"
