#!/usr/bin/env bash
#MISE description="terragrunt apply for a prod deployment stack (builds providers, escalates to the write SA, renders creds from 1Password). SITE selects the stack."
set -euo pipefail
ROOT=$(git rev-parse --show-toplevel)

# OpenTofu doesn't read the macOS keychain, so the OVH S3 backend cert fails to
# verify locally — point at the system CA bundle; Linux/CI is fine untouched.
if [ -z "${SSL_CERT_FILE:-}" ] && [ "$(uname -s)" = "Darwin" ] && [ -f /etc/ssl/cert.pem ]; then
  export SSL_CERT_FILE=/etc/ssl/cert.pem AWS_CA_BUNDLE=/etc/ssl/cert.pem
fi

mise run infra:providers

# Escalate to the write SA stored in-vault: read it with the read-scoped token
# (CI's OP_SERVICE_ACCOUNT_TOKEN, or a team-futo sign-in locally) and apply as
# it. One GitHub secret suffices; the write privilege lives in 1Password.
ACCT=(); [ -z "${OP_SERVICE_ACCOUNT_TOKEN:-}" ] && ACCT=(--account "${OP_ACCOUNT:-team-futo}")
OP_SERVICE_ACCOUNT_TOKEN=$(op read "${ACCT[@]}" \
  "op://yucca_tf_prod/yucca_futo_1pass_service_account_write/password")
export OP_SERVICE_ACCOUNT_TOKEN

# Render the NETCONF SSH key from 1Password to a 0600 temp file (op run can't
# write files) — now via the escalated SA. DETERMINISTIC path: must match the
# plan job's render exactly (the value lives inside the saved plan).
KEYF="${RUNNER_TEMP:-${TMPDIR:-/tmp}}/netconf-terraform-key"
rm -f "$KEYF"; ( umask 077; : > "$KEYF" ); trap 'rm -f "$KEYF"' EXIT
op read "op://yucca_tf_prod/NET_SWITCHES_TERRAFORM_SSH_PRIVATE_KEY/password" > "$KEYF"

export TF_VAR_netconf_ssh_key_path="$KEYF"
export TF_CLI_CONFIG_FILE="$ROOT/tf/.terraformrc.local"
SITE="${SITE:-htz-fsn1}"
# With a service-account token in the env, drop OP_ACCOUNT — the onepassword
# provider rejects having both set ("service_account_token and account are set").
unset OP_ACCOUNT
STACK_DIR="tf/deployment/prod/$SITE/fabric"

# When CI passes TG_PLAN, apply THAT file (no re-plan, no -auto-approve; tofu
# fails closed on a stale plan) and strip any -auto-approve (meaningless with a
# plan file). Unset TG_PLAN (local runs) keeps interactive/-auto-approve behaviour.
APPLY_ARGS=("$@")
if [ -n "${TG_PLAN:-}" ]; then
  [ -f "$TG_PLAN" ] || { echo "infra:apply: TG_PLAN set but plan file missing: $TG_PLAN" >&2; exit 1; }
  filtered=(); for a in "${APPLY_ARGS[@]}"; do [ "$a" = "-auto-approve" ] && continue; filtered+=("$a"); done
  APPLY_ARGS=("${filtered[@]}" "$TG_PLAN")
fi

# jeremmfr/junos is concurrency-safe (commits serialize on the per-device config
# lock); device NETCONF connection-limit raised to 250.
OP_ENV_FILE=tf/.env.prod "$ROOT/tf/op-run.sh" terragrunt --working-dir "$STACK_DIR" apply -parallelism=4 "${APPLY_ARGS[@]}"

# Confirm jeremmfr's dangling `commit confirmed`: its "confirm" is `commit
# check`, which does NOT cancel the rollback on our Junos — without a plain
# `commit` the last change auto-reverts. Runs ONLY after a successful apply
# (set -e), so a mgmt-breaking apply skips it and the rollback restores
# management; nothing pending -> harmless no-op.
echo "==> confirming commit-confirmed on managed switches"
IPS=$(OP_ENV_FILE=tf/.env.prod "$ROOT/tf/op-run.sh" terragrunt --working-dir "$STACK_DIR" output -json switch_mgmt_ips | tr -d '[]" ' | tr ',' '\n')
KH=$(mktemp); trap 'rm -f "$KEYF" "$KH"' EXIT
for ip in $IPS; do
  [ -n "$ip" ] || continue
  ok=
  for attempt in 1 2 3; do
    if ssh -i "$KEYF" -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new \
         -o UserKnownHostsFile="$KH" -o ConnectTimeout=15 -o NumberOfPasswordPrompts=0 \
         -o BatchMode=yes "terraform@$ip" "configure; commit; exit" >/dev/null 2>&1; then
      ok=1; echo "    confirmed $ip"; break
    fi
    echo "    confirm attempt $attempt failed on $ip; retrying..."; sleep 5
  done
  [ -n "$ok" ] || { echo "ERROR: could not confirm commit on $ip — its last change will roll back (commit_confirmed). Investigate." >&2; exit 1; }
done
