#!/usr/bin/env bash
# ════════════════════════════════════════════════════════════════
# 光湖 · 按量计费CVM自动开关机
# 开机/关机/状态查询
# ════════════════════════════════════════════════════════════════
#
# 用法:
#   bash cvm-power.sh start    # 开机
#   bash cvm-power.sh stop     # 关机
#   bash cvm-power.sh status   # 查看状态
#
# 环境变量（从Vault或Forgejo Secrets读取）:
#   TENCENT_SECRET_ID    腾讯云API SecretId
#   TENCENT_SECRET_KEY   腾讯云API SecretKey
#   CVM_INSTANCE_ID      CVM实例ID (ins-xxxxx)
#   CVM_REGION           地域 (ap-guangzhou)
#
# ════════════════════════════════════════════════════════════════

set -euo pipefail

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

# 配置
SECRET_ID="${TENCENT_SECRET_ID:-}"
SECRET_KEY="${TENCENT_SECRET_KEY:-}"
INSTANCE_ID="${CVM_INSTANCE_ID:-}"
REGION="${CVM_REGION:-ap-guangzhou}"
SERVICE="cvm"
HOST="cvm.tencentcloudapi.com"
API_VERSION="2017-03-12"

# 检查配置
if [[ -z "$SECRET_ID" || -z "$SECRET_KEY" || -z "$INSTANCE_ID" ]]; then
  echo -e "${RED}❌ 缺少环境变量${NC}"
  echo "需要: TENCENT_SECRET_ID, TENCENT_SECRET_KEY, CVM_INSTANCE_ID"
  echo "请在Forgejo Secrets中配置这些值"
  exit 1
fi

# ─── 腾讯云API签名 ──────────────────────────────────────────────

call_api() {
  local action=$1
  local payload=$2

  local timestamp=$(date +%s)
  local date=$(date -u -d "@$timestamp" +%Y-%m-%d 2>/dev/null || date -u +%Y-%m-%d)

  # 1. 拼接规范请求串
  local http_method="POST"
  local canonical_uri="/"
  local canonical_querystring=""
  local ct="application/json; charset=utf-8"
  local hashed_payload=$(echo -n "$payload" | sha256sum | awk '{print $1}')
  local canonical_headers="content-type:${ct}\nhost:${HOST}\nx-tc-action:${action,,}\n"
  local signed_headers="content-type;host;x-tc-action"
  local canonical_request="${http_method}\n${canonical_uri}\n${canonical_querystring}\n${canonical_headers}\n${signed_headers}\n${hashed_payload}"

  # 2. 拼接待签名字符串
  local algorithm="TC3-HMAC-SHA256"
  local credential_scope="${date}/${SERVICE}/tc3_request"
  local hashed_canonical=$(echo -n "$canonical_request" | sha256sum | awk '{print $1}')
  local string_to_sign="${algorithm}\n${timestamp}\n${credential_scope}\n${hashed_canonical}"

  # 3. 计算签名
  local secret_date=$(echo -n "$date" | openssl dgst -sha256 -hmac "TC3${SECRET_KEY}" -binary | xxd -p -c 256)
  local secret_service=$(echo -n "$SERVICE" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$secret_date" -binary | xxd -p -c 256)
  local secret_signing=$(echo -n "tc3_request" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$secret_service" -binary | xxd -p -c 256)
  local signature=$(echo -n "$string_to_sign" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$secret_signing" | awk '{print $NF}')

  # 4. 构造Authorization
  local authorization="${algorithm} Credential=${SECRET_ID}/${credential_scope}, SignedHeaders=${signed_headers}, Signature=${signature}"

  # 5. 发送请求
  curl -s -X POST "https://${HOST}" \
    -H "Authorization: ${authorization}" \
    -H "Content-Type: ${ct}" \
    -H "Host: ${HOST}" \
    -H "X-TC-Action: ${action}" \
    -H "X-TC-Timestamp: ${timestamp}" \
    -H "X-TC-Version: ${API_VERSION}" \
    -H "X-TC-Region: ${REGION}" \
    -d "$payload"
}

# ─── 操作函数 ───────────────────────────────────────────────────

do_start() {
  echo -e "${YELLOW}[开机] 正在启动CVM ${INSTANCE_ID}...${NC}"
  local payload="{\"InstanceIds\":[\"${INSTANCE_ID}\"]}"
  local resp=$(call_api "StartInstances" "$payload")

  if echo "$resp" | python3 -c "
import json,sys
d=json.load(sys.stdin)
if 'Response' in d and 'Error' not in d['Response']:
    print('OK')
else:
    err=d.get('Response',{}).get('Error',{}).get('Message','未知错误')
    print(f'ERROR: {err}')
" 2>/dev/null | grep -q "OK"; then
    echo -e "${GREEN}✅ 开机指令已发送${NC}"
    echo "   等待实例启动（约1-2分钟）..."
    wait_for_ssh
  else
    echo -e "${RED}❌ 开机失败${NC}"
    echo "$resp" | python3 -c "import json,sys;d=json.load(sys.stdin);print(d.get('Response',{}).get('Error',{}).get('Message','未知'))" 2>/dev/null
    exit 1
  fi
}

do_stop() {
  echo -e "${YELLOW}[关机] 正在停止CVM ${INSTANCE_ID}...${NC}"
  local payload="{\"InstanceIds\":[\"${INSTANCE_ID}\"]}"
  local resp=$(call_api "StopInstances" "$payload")

  if echo "$resp" | python3 -c "
import json,sys
d=json.load(sys.stdin)
if 'Response' in d and 'Error' not in d['Response']:
    print('OK')
else:
    err=d.get('Response',{}).get('Error',{}).get('Message','未知错误')
    print(f'ERROR: {err}')
" 2>/dev/null | grep -q "OK"; then
    echo -e "${GREEN}✅ 关机指令已发送${NC}"
    echo "   实例将在几分钟内完全停止"
    echo "   停止后不再收取计算费用（仅收云盘费用）"
  else
    echo -e "${RED}❌ 关机失败${NC}"
    echo "$resp" | python3 -c "import json,sys;d=json.load(sys.stdin);print(d.get('Response',{}).get('Error',{}).get('Message','未知'))" 2>/dev/null
    exit 1
  fi
}

do_status() {
  echo -e "${YELLOW}[状态] 查询CVM ${INSTANCE_ID}...${NC}"
  local payload="{\"InstanceIds\":[\"${INSTANCE_ID}\"]}"
  local resp=$(call_api "DescribeInstancesStatus" "$payload")

  echo "$resp" | python3 -c "
import json,sys
d=json.load(sys.stdin)
r=d.get('Response',{})
statuses=r.get('InstanceStatusSet',[])
if not statuses:
    print('  状态: 未找到实例')
else:
    state=statuses[0].get('InstanceState','UNKNOWN')
    icon={'RUNNING':'🟢','STOPPED':'🔴','STARTING':'🟡','STOPPING':'🟡'}.get(state,'⚪')
    print(f'  {icon} 实例状态: {state}')
" 2>/dev/null || echo "  查询失败"
}

wait_for_ssh() {
  local max_wait=120
  local waited=0
  local ip=$(get_instance_ip)

  if [[ -z "$ip" ]]; then
    echo "   ⚠️ 无法获取公网IP，请手动检查"
    return
  fi

  echo -n "   等待SSH可连 (${ip}:22) "
  while [[ $waited -lt $max_wait ]]; do
    if timeout 3 bash -c "echo >/dev/tcp/${ip}/22" 2>/dev/null; then
      echo ""
      echo -e "${GREEN}   ✅ CVM已就绪: ${ip}${NC}"
      return
    fi
    echo -n "."
    sleep 5
    waited=$((waited + 5))
  done
  echo ""
  echo "   ⚠️ SSH连接超时，实例可能还在启动中"
}

get_instance_ip() {
  local payload="{\"InstanceIds\":[\"${INSTANCE_ID}\"]}"
  call_api "DescribeInstances" "$payload" | python3 -c "
import json,sys
d=json.load(sys.stdin)
instances=d.get('Response',{}).get('InstanceSet',[])
if instances:
    ip=instances[0].get('PublicIpAddresses',[])[0] if instances[0].get('PublicIpAddresses') else ''
    print(ip)
" 2>/dev/null || echo ""
}

# ─── 入口 ─────────────────────────────────────────────────────

case "${1:-}" in
  start)  do_start  ;;
  stop)   do_stop   ;;
  status) do_status ;;
  *)
    echo "用法: bash cvm-power.sh {start|stop|status}"
    echo ""
    echo "  start  - 开机（按量计费CVM）"
    echo "  stop   - 关机（停止计费）"
    echo "  status - 查询状态"
    exit 1
    ;;
esac
