#!/bin/bash
# =============================================================================
# ccp-deregister.sh — Remove this host's Instance from the CCP
#
# Pairs with scripts/pangolin-teardown.sh. Use when wiping a test instance
# that was phone-home-registered with a CCP. Without this, the CCP retains
# a stale Instance row after the underlying stack is gone and will block
# re-registration of the same slug (CCP's slug-collision behaviour).
#
# Credentials are read from .env (CCP_URL, CCP_AGENT_URL) and a CCP admin
# token, unless overridden by flags.
#
# Usage:
#   ./scripts/ccp-deregister.sh --token CCP_ADMIN_TOKEN
#   ./scripts/ccp-deregister.sh --token T --yes        # execute (default: dry-run)
#   ./scripts/ccp-deregister.sh --ccp-url URL --agent-url URL --token T --yes
#
# Matching: by default, matches Instances whose agentUrl equals this host's
# CCP_AGENT_URL. Pass --slug SLUG or --instance-id ID for explicit targeting.
#
# Exit codes: 0 success, 1 error, 2 nothing matched
# =============================================================================
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="${PROJECT_DIR}/.env"

RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'

CCP_URL=""; CCP_AGENT_URL=""; TOKEN=""; SLUG=""; INSTANCE_ID=""
CONFIRM=false

usage() {
  sed -n '2,22p' "$0" | sed 's/^# \?//'
  exit 0
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --yes|-y)       CONFIRM=true; shift ;;
    --ccp-url)      CCP_URL="$2"; shift 2 ;;
    --agent-url)    CCP_AGENT_URL="$2"; shift 2 ;;
    --token)        TOKEN="$2"; shift 2 ;;
    --slug)         SLUG="$2"; shift 2 ;;
    --instance-id)  INSTANCE_ID="$2"; shift 2 ;;
    -h|--help)      usage ;;
    *) echo "Unknown flag: $1"; exit 1 ;;
  esac
done

# Load missing fields from .env
if [[ -z "$CCP_URL" || -z "$CCP_AGENT_URL" ]]; then
  if [[ -f "$ENV_FILE" ]]; then
    CCP_URL="${CCP_URL:-$(grep -E '^CCP_URL=' "$ENV_FILE" | head -1 | cut -d= -f2-)}"
    CCP_AGENT_URL="${CCP_AGENT_URL:-$(grep -E '^CCP_AGENT_URL=' "$ENV_FILE" | head -1 | cut -d= -f2-)}"
  fi
fi

# Token may also come from env var
TOKEN="${TOKEN:-${CCP_ADMIN_TOKEN:-}}"

if [[ -z "$CCP_URL" ]]; then
  echo -e "${RED}ERROR:${NC} CCP_URL not set. Pass --ccp-url or set in .env."
  exit 1
fi
if [[ -z "$TOKEN" ]]; then
  echo -e "${RED}ERROR:${NC} No CCP admin token. Pass --token or set CCP_ADMIN_TOKEN env var."
  echo "  Obtain via: curl -X POST \$CCP_URL/api/auth/login -d @login.json"
  exit 1
fi

if ! command -v python3 >/dev/null 2>&1; then
  echo -e "${RED}ERROR:${NC} python3 is required for JSON parsing"
  exit 1
fi

echo -e "${BOLD}CCP deregister${NC}"
echo "  CCP:         $CCP_URL"
[[ -n "$CCP_AGENT_URL" ]] && echo "  Agent URL:   $CCP_AGENT_URL  (match target)"
[[ -n "$SLUG" ]] && echo "  Slug:        $SLUG  (match target)"
[[ -n "$INSTANCE_ID" ]] && echo "  Instance ID: $INSTANCE_ID  (explicit)"
[[ "$CONFIRM" == "false" ]] && echo -e "  ${YELLOW}Mode: DRY RUN${NC} (pass --yes to execute)"
echo ""

# Fetch instances
RAW=$(curl -sf -H "Authorization: Bearer $TOKEN" "$CCP_URL/api/instances" 2>&1 || true)
if [[ -z "$RAW" ]]; then
  echo -e "${RED}ERROR:${NC} Could not fetch /api/instances (check token + URL)"
  exit 1
fi

# Build match list — the API may wrap instances in {data: [...]} or return raw [].
# Also: the /api/instances list omits pangolinEndpoint for brevity, so match fields are scoped to slug/agentUrl/id.
MATCHES=$(echo "$RAW" | python3 -c "
import sys, json
d = json.load(sys.stdin)
items = d.get('data', d) if isinstance(d, dict) else d
target_slug = '${SLUG}' or None
target_id = '${INSTANCE_ID}' or None
target_agent = '${CCP_AGENT_URL}' or None

for inst in items:
    if target_id:
        if inst.get('id') == target_id:
            print(f\"{inst['id']}\t{inst.get('slug','?')}\t{inst.get('agentUrl','?')}\")
    elif target_slug:
        if inst.get('slug') == target_slug:
            print(f\"{inst['id']}\t{inst.get('slug','?')}\t{inst.get('agentUrl','?')}\")
    elif target_agent:
        if inst.get('agentUrl') == target_agent:
            print(f\"{inst['id']}\t{inst.get('slug','?')}\t{inst.get('agentUrl','?')}\")
")

MATCH_COUNT=$(echo -n "$MATCHES" | grep -c . || true)
echo -e "${CYAN}Matches: $MATCH_COUNT${NC}"
if [[ "$MATCH_COUNT" -eq 0 ]]; then
  echo "  (no instances matched the criteria)"
  exit 2
fi
echo "$MATCHES" | awk -F'\t' '{printf "  - [%s] slug=%s agentUrl=%s\n", $1, $2, $3}'

if [[ "$CONFIRM" == "false" ]]; then
  echo ""
  echo -e "${YELLOW}Dry run complete.${NC} Re-run with --yes to actually delete."
  exit 0
fi

echo ""
echo -e "${BOLD}Deleting...${NC}"

FAILURES=0
while IFS=$'\t' read -r iid slug aurl; do
  [[ -z "$iid" ]] && continue
  code=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
    "$CCP_URL/api/instances/$iid" \
    -H "Authorization: Bearer $TOKEN")
  if [[ "$code" == "200" || "$code" == "204" ]]; then
    echo -e "  ${GREEN}OK${NC}   instance $iid ($slug) deleted"
  else
    echo -e "  ${RED}FAIL${NC} instance $iid ($slug) HTTP $code"
    FAILURES=$((FAILURES + 1))
  fi
done <<< "$MATCHES"

if [[ $FAILURES -gt 0 ]]; then
  echo -e "${YELLOW}Completed with $FAILURES failure(s).${NC}"
  exit 2
fi
echo -e "${GREEN}Deregister complete.${NC}"
