#!/usr/bin/env bash
# filepath: deploy.sh
# git clone https://code.deep-pilot.chat/AI_POC/TERES_web_frontend.git

set -e
if [ -n "${BASH_VERSION:-}" ]; then
  set -o pipefail
fi

# 固定镜像名（兼容你原 stop.sh 的做法）
IMAGE_NAME="teres_web_frontend:latest"
FLASK_IMAGE_NAME="teres_web_frontend_flask:latest"
SERVICE_NAME="teres_web_frontend"
NETWORK_NAME="proxy-net"

usage() {
  cat <<'EOF'
用法: ./deploy.sh <命令> [选项]

常用命令:
  start            拉最新代码并构建启动（docker compose up -d --build）
  stop             按固定镜像名停止并删除容器，同时删除镜像
  restart          先 stop 再 start
  clean            同 stop（停止容器并删除镜像）

增强命令:
  status           查看服务状态（compose ps + 过滤容器）
  logs [--follow]  查看日志（加 --follow 跟随）
  health           健康检查（HTTP 200）
  set [opts]       更新 .env 中 PORT/BUILD_MODE/RAGFLOW_BASE
  pull             仅拉取最新代码
  prune            清理悬空镜像与缓存

set 支持的选项:
  --port <N>            设置端口（映射和构建参数）
  --mode <production|flask>  设置构建模式，选择 .env.production 或 .env.flask
  --base <path>         设置 ragflow 子路径（默认 /ragflow/）

示例:
  ./deploy.sh start
  ./deploy.sh set --port 5173 --mode production --base /ragflow/
  ./deploy.sh logs --follow
  ./deploy.sh health
EOF
}

# 检查命令存在
require_cmd() {
  local cmd="$1"; command -v "$cmd" >/dev/null 2>&1 || {
    echo "错误: 未找到命令 '$cmd'"; exit 1; }
}

# 选择 compose 命令
compose_cmd() {
  if command -v docker-compose >/dev/null 2>&1; then
    echo docker-compose
  else
    echo docker compose
  fi
}

ensure_network() {
  if ! docker network inspect "$NETWORK_NAME" >/dev/null 2>&1; then
    echo "--- 创建网络: $NETWORK_NAME ---"
    docker network create "$NETWORK_NAME"
  fi
}

git_pull() {
  echo "--- 拉取最新的代码 ---"
  git fetch --all --prune || true
  git pull
}

compose_up() {
  local cmd; cmd=$(compose_cmd)
  ensure_network
  echo "--- docker compose 构建并启动 ---"
  $cmd up -d --build
}

compose_down() {
  local cmd; cmd=$(compose_cmd)
  echo "--- docker compose down ---"
  $cmd down || true
}

stop_by_image() {
  local image="$1"
  echo "--- 停止并删除镜像对应的容器: $image ---"
  local ids
  ids=$(docker ps -a --filter "ancestor=$image" --format "{{.ID}}" || true)
  if [[ -n "$ids" ]]; then
    for id in $ids; do
      docker stop "$id" || true
      docker rm "$id" || true
    done
  fi
  echo "--- 删除镜像: $image ---"
  docker rmi "$image" || true
}

status() {
  local cmd; cmd=$(compose_cmd)
  echo "--- compose ps ---"
  $cmd ps || true
  echo "--- docker ps (过滤 $SERVICE_NAME) ---"
  docker ps --format '{{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Status}}' | grep -E "$SERVICE_NAME|$IMAGE_NAME" || true
}

logs() {
  local follow="false"
  if [[ "${1:-}" == "--follow" ]]; then follow="true"; fi
  local cmd; cmd=$(compose_cmd)
  if [[ "$follow" == "true" ]]; then
    $cmd logs -f "$SERVICE_NAME"
  else
    $cmd logs --tail=300 "$SERVICE_NAME"
  fi
}

# 更新 .env 中某个键值（若不存在则追加）
update_env_var() {
  local key="$1"; shift
  local val="$1"; shift
  touch .env
  if grep -qE "^\s*${key}\s*=\s*" .env; then
    # 使用正则替换整行，保留键名
    sed -i.bak -E "s|^\s*(${key})\s*=\s*.*|\1=${val}|" .env
  else
    echo "${key}=${val}" >> .env
  fi
}

health() {
  # 从 .env 读取，带默认值
  local PORT=${PORT:-$(grep -E '^\s*PORT\s*=' .env | sed -E 's/.*=\s*//g' || echo 5173)}
  local BASE=${RAGFLOW_BASE:-$(grep -E '^\s*RAGFLOW_BASE\s*=' .env | sed -E 's/.*=\s*//g' || echo /ragflow/)}
  local host="http://127.0.0.1:${PORT}"
  echo "--- 健康检查: ${host} 与 ${host}${BASE} ---"
  if command -v curl >/dev/null 2>&1; then
    curl -fsS -o /dev/null "${host}" && echo "根应用 OK" || echo "根应用失败"
    curl -fsS -o /dev/null "${host}${BASE}" && echo "ragflow 子路径 OK" || echo "ragflow 子路径失败"
  else
    wget -q --spider "${host}" && echo "根应用 OK" || echo "根应用失败"
    wget -q --spider "${host}${BASE}" && echo "ragflow 子路径 OK" || echo "ragflow 子路径失败"
  fi
}

prune() {
  echo "--- 清理悬空镜像与构建缓存 ---"
  docker image prune -f || true
  docker builder prune -f || true
}

cmd_start() {
  git_pull
  compose_up
}

cmd_stop() {
  compose_down
  stop_by_image "$IMAGE_NAME"
  stop_by_image "$FLASK_IMAGE_NAME"
}

cmd_restart() {
  cmd_stop
  cmd_start
}

cmd_clean() { cmd_stop; }

cmd_pull() { git_pull; }

cmd_set() {
  # 解析选项
  local port="" mode="" base=""
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --port) port="$2"; shift 2;;
      --mode) mode="$2"; shift 2;;
      --base) base="$2"; shift 2;;
      *) echo "未知选项: $1"; usage; exit 1;;
    esac
  done
  [[ -n "$port" ]] && update_env_var PORT "$port"
  [[ -n "$mode" ]] && update_env_var BUILD_MODE "$mode"
  [[ -n "$base" ]] && update_env_var RAGFLOW_BASE "$base"
  echo "--- .env 已更新 ---"
}

main() {
  require_cmd docker
  local subcmd="${1:-}"
  case "$subcmd" in
    start) shift; cmd_start "$@" ;;
    stop) shift; cmd_stop "$@" ;;
    restart) shift; cmd_restart "$@" ;;
    clean) shift; cmd_clean "$@" ;;
    status) shift; status "$@" ;;
    logs) shift; logs "${1:-}" ;;
    health) shift; health "$@" ;;
    set) shift; cmd_set "$@" ;;
    pull) shift; cmd_pull "$@" ;;
    prune) shift; prune "$@" ;;
    ""|help|-h|--help) usage ;;
    *) echo "未知命令: $subcmd"; usage; exit 1 ;;
  esac
  echo "--- 完成 ---"
}

main "$@"