#!/usr/bin/env bash
# ============================================================================
# Example: External tool triggers maintenance via ss-tools API (bash)
#
# This script shows how to call the ss-tools maintenance API from any
# shell environment — CI/CD pipeline, cron job, or ad-hoc debugging.
#
# Prerequisites:
#   - curl, jq (optional, for pretty-printing JSON)
#   - An ss-tools API key with `maintenance:start`, `maintenance:end`
#
# Usage:
#   ./maintenance-api-bash.sh start "public.messages" 4 "ss-dev"
#   ./maintenance-api-bash.sh end "m-abc123"
#   ./maintenance-api-bash.sh end-all "ss-dev"
# ============================================================================

set -euo pipefail

# ── Configuration ──────────────────────────────────────────────────────────
# Set these via environment variables or replace inline
BASE_URL="${SS_TOOLS_URL:-http://localhost:8000}"
API_KEY="${SS_TOOLS_API_KEY:-}"

# ── Color helpers (disabled in non-TTY) ────────────────────────────────────
if [[ -t 1 ]]; then
  GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'
  CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
else
  GREEN=''; RED=''; YELLOW=''; CYAN=''; BOLD=''; NC=''
fi

ok()   { echo -e "${GREEN}✅${NC} $*"; }
info() { echo -e "${CYAN}ℹ️ ${NC} $*"; }
warn() { echo -e "${YELLOW}⚠️ ${NC} $*"; }
fail() { echo -e "${RED}❌${NC} $*"; exit 1; }

# ── Auth check ─────────────────────────────────────────────────────────────
check_auth() {
  if [[ -z "$API_KEY" ]]; then
    fail "API key not set. Export SS_TOOLS_API_KEY or edit the script."
  fi
}

# ── API helpers ────────────────────────────────────────────────────────────

# Call the API with X-API-Key auth and handle common errors
api_call() {
  local method="$1"    # GET / POST
  local endpoint="$2"  # /api/maintenance/start
  local data="$3"      # JSON payload or empty string

  local curl_args=(
    -X "$method"
    -sS
    -H "X-API-Key: $API_KEY"
    -H "Content-Type: application/json"
  )

  if [[ -n "$data" ]]; then
    curl_args+=(-d "$data")
  fi

  local http_code
  local response_file
  response_file=$(mktemp)

  http_code=$(curl -w '%{http_code}' "${curl_args[@]}" \
    "${BASE_URL}${endpoint}" \
    -o "$response_file" 2>/dev/null)

  local body
  body=$(<"$response_file")
  rm -f "$response_file"

  case "$http_code" in
    202)
      echo "$body"  # success
      return 0
      ;;
    400)
      warn "Validation error:"
      echo "$body" | jq . 2>/dev/null || echo "$body"
      return 1
      ;;
    401)
      fail "Authentication failed: invalid or revoked API key"
      ;;
    403)
      fail "Permission denied: API key lacks required permission"
      ;;
    404)
      local status
      status=$(echo "$body" | jq -r '.status // "not_found"' 2>/dev/null)
      if [[ "$status" == "already_completed" ]]; then
        info "Event was already completed (idempotent)"
        return 0
      fi
      warn "Not found (404):"
      echo "$body" | jq . 2>/dev/null || echo "$body"
      return 1
      ;;
    *)
      fail "Unexpected HTTP $http_code: $(echo "$body" | head -c 500)"
      ;;
  esac
}

# ── Commands ───────────────────────────────────────────────────────────────

cmd_start() {
  local tables="$1"
  local duration_hours="${2:-4}"
  local environment_id="$3"
  local message="${4:-}"

  local start_time
  local end_time
  start_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
  end_time=$(date -u -d "+${duration_hours} hours" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null \
          || date -u -v "+${duration_hours}H" +"%Y-%m-%dT%H:%M:%SZ")

  # Build JSON payload
  local payload
  payload=$(cat <<EOF
{
  "tables": [$(echo "$tables" | sed 's/[^,]*/"&"/g')],
  "start_time": "$start_time",
  "end_time": "$end_time",
  "environment_id": "$environment_id"
EOF
)
  if [[ -n "$message" ]]; then
    payload="$payload"$',\n  "message": "'"$message"'"'
  fi
  payload="$payload"$'\n}'

  info "Starting maintenance: tables=${tables}, env=${environment_id}, ${duration_hours}h"
  info "Window: ${start_time} → ${end_time}"

  local response
  if response=$(api_call POST "/api/maintenance/start" "$payload"); then
    local event_id
    event_id=$(echo "$response" | jq -r '.maintenance_id' 2>/dev/null || echo "unknown")
    local task_id
    task_id=$(echo "$response" | jq -r '.task_id' 2>/dev/null || echo "unknown")
    ok "Maintenance event created: ${BOLD}${event_id}${NC}"
    info "Task: ${task_id}"
    echo "$response" | jq . 2>/dev/null || echo "$response"
  fi
}

cmd_end() {
  local event_id="$1"

  info "Ending maintenance event: ${event_id}"

  local response
  if response=$(api_call POST "/api/maintenance/${event_id}/end" ""); then
    ok "Maintenance event end scheduled"
    echo "$response" | jq . 2>/dev/null || echo "$response"
  fi
}

cmd_end_all() {
  local environment_id="${1:-}"

  warn "This will remove banners from ALL affected dashboards!"
  if [[ -n "$environment_id" ]]; then
    info "Scope: environment=${environment_id}"
  else
    info "Scope: all environments (API key default)"
  fi

  # Prompt for confirmation in interactive mode
  if [[ -t 0 ]]; then
    echo -n "Continue? [y/N] "
    read -r confirm
    if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
      info "Cancelled."
      exit 0
    fi
  fi

  local payload="{}"
  if [[ -n "$environment_id" ]]; then
    payload=$(cat <<EOF
{"environment_id": "$environment_id"}
EOF
)
  fi

  local response
  if response=$(api_call POST "/api/maintenance/end-all" "$payload"); then
    ok "End-all scheduled"
    echo "$response" | jq . 2>/dev/null || echo "$response"
  fi
}

# ── Main ───────────────────────────────────────────────────────────────────

check_auth

case "${1:-help}" in
  start)
    if [[ $# -lt 3 ]]; then
      echo "Usage: $0 start <tables> [duration_hours] <environment> [message]"
      echo ""
      echo "Examples:"
      echo "  $0 start public.messages 4 ss-dev"
      echo "  $0 start public.messages,public.users 4 ss-prod \"Scheduled ETL\""
      exit 1
    fi
    cmd_start "$2" "${3:-4}" "${4:-}" "${5:-}"
    ;;
  end)
    if [[ $# -lt 2 ]]; then
      echo "Usage: $0 end <event-id>"
      exit 1
    fi
    cmd_end "$2"
    ;;
  end-all)
    cmd_end_all "${2:-}"
    ;;
  *)
    cat <<EOF
ss-tools Maintenance CLI

Usage:
  $0 start <tables> [hours=4] <environment> [message]
      Start maintenance on tables (comma-separated)

  $0 end <event-id>
      End a specific maintenance event

  $0 end-all [environment]
      End ALL maintenance (use with caution)

Examples:
  $0 start public.messages 4 ss-dev
  $0 end m-abc123
  $0 end-all ss-dev

Environment:
  SS_TOOLS_URL      ss-tools base URL (default: http://localhost:8000)
  SS_TOOLS_API_KEY  API key with required permissions (required)
EOF
    exit 0
    ;;
esac
