#!/bin/bash
# 一键生成生产环境服务文件脚本（静默安装）
# 包括：Caddy 安装、后端服务 systemd 文件、Caddy 服务 systemd 文件
# 
# 用法:
#   ./setup_production.sh              # 静默安装所有内容（默认）
#   ./setup_production.sh --no-install # 只生成服务文件，不安装到系统

set -e

# 获取脚本所在目录（项目根目录）
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR" || exit 1

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 打印函数
info() { echo -e "${BLUE}ℹ${NC} $1"; }
success() { echo -e "${GREEN}✓${NC} $1"; }
warn() { echo -e "${YELLOW}⚠${NC} $1"; }
error() { echo -e "${RED}✗${NC} $1"; }

# 配置变量
CADDY_VERSION="2.10.2"
CADDY_ARCH="linux_amd64"
CADDY_URL="https://github.com/caddyserver/caddy/releases/download/v${CADDY_VERSION}/caddy_${CADDY_VERSION}_${CADDY_ARCH}.tar.gz"
CADDY_BINARY="caddy"
CADDY_INSTALL_DIR="/usr/local/bin"
CADDY_CONFIG_DIR="/etc/caddy"
CADDY_DATA_DIR="/var/lib/caddy"

PROJECT_ROOT="$SCRIPT_DIR"
JINGROW_APP_DIR="$PROJECT_ROOT/apps/jingrow"
SERVICE_USER="${SERVICE_USER:-$(whoami)}"
SERVICE_GROUP="${SERVICE_GROUP:-$(id -gn)}"
TMP_DIR="$PROJECT_ROOT/tmp"

# 检测 uv 路径
detect_uv_path() {
    if command -v uv &> /dev/null; then
        UV_PATH=$(command -v uv)
        info "检测到 uv 路径: $UV_PATH"
    else
        # 尝试常见路径
        if [ -f "$HOME/.local/bin/uv" ]; then
            UV_PATH="$HOME/.local/bin/uv"
        elif [ -f "/usr/local/bin/uv" ]; then
            UV_PATH="/usr/local/bin/uv"
        else
            error "未找到 uv，请先安装"
            exit 1
        fi
        warn "使用 uv 路径: $UV_PATH"
    fi
}

# 检测系统架构
detect_arch() {
    local arch=$(uname -m)
    case "$arch" in
        x86_64|amd64)
            CADDY_ARCH="linux_amd64"
            ;;
        aarch64|arm64)
            CADDY_ARCH="linux_arm64"
            ;;
        armv7l|armv6l)
            CADDY_ARCH="linux_armv7"
            ;;
        *)
            error "不支持的架构: $arch"
            exit 1
            ;;
    esac
    CADDY_URL="https://github.com/caddyserver/caddy/releases/download/v${CADDY_VERSION}/caddy_${CADDY_VERSION}_${CADDY_ARCH}.tar.gz"
    info "检测到架构: $arch，使用 $CADDY_ARCH"
}

# 创建 Caddyfile 符号链接
setup_caddyfile_link() {
    # 创建必要的目录
    if [ "$EUID" -eq 0 ]; then
        mkdir -p "$CADDY_CONFIG_DIR" "$CADDY_DATA_DIR"
        chown -R "$SERVICE_USER:$SERVICE_GROUP" "$CADDY_CONFIG_DIR" "$CADDY_DATA_DIR" 2>/dev/null || true
    else
        sudo mkdir -p "$CADDY_CONFIG_DIR" "$CADDY_DATA_DIR"
        sudo chown -R "$SERVICE_USER:$SERVICE_GROUP" "$CADDY_CONFIG_DIR" "$CADDY_DATA_DIR" 2>/dev/null || true
    fi
    
    # 创建 Caddyfile 符号链接
    if [ -f "$PROJECT_ROOT/Caddyfile" ]; then
        info "创建 Caddyfile 符号链接..."
        # 如果已存在文件或链接，先删除
        if [ "$EUID" -eq 0 ]; then
            [ -e "$CADDY_CONFIG_DIR/Caddyfile" ] && rm -f "$CADDY_CONFIG_DIR/Caddyfile"
            ln -s "$PROJECT_ROOT/Caddyfile" "$CADDY_CONFIG_DIR/Caddyfile"
        else
            [ -e "$CADDY_CONFIG_DIR/Caddyfile" ] && sudo rm -f "$CADDY_CONFIG_DIR/Caddyfile"
            sudo ln -s "$PROJECT_ROOT/Caddyfile" "$CADDY_CONFIG_DIR/Caddyfile"
        fi
        success "Caddyfile 符号链接已创建: $CADDY_CONFIG_DIR/Caddyfile -> $PROJECT_ROOT/Caddyfile"
    else
        warn "未找到 Caddyfile，请手动创建符号链接: ln -s $PROJECT_ROOT/Caddyfile $CADDY_CONFIG_DIR/Caddyfile"
    fi
}

# 安装 Caddy
install_caddy() {
    info "开始安装 Caddy ${CADDY_VERSION}..."
    
    # 检查是否已安装
    if command -v caddy &> /dev/null; then
        local installed_version=$(caddy version 2>/dev/null | head -n1 | grep -oP 'v\d+\.\d+\.\d+' || echo "unknown")
        info "Caddy 已安装，版本: $installed_version，跳过二进制安装"
    else
        # 创建临时目录
        local tmp_dir=$(mktemp -d)
        trap "rm -rf $tmp_dir" EXIT
        
        info "下载 Caddy..."
        local caddy_tar="$tmp_dir/caddy.tar.gz"
        if ! curl -L -o "$caddy_tar" "$CADDY_URL"; then
            error "下载 Caddy 失败"
            exit 1
        fi
        
        info "解压 Caddy..."
        cd "$tmp_dir"
        tar -xzf "$caddy_tar"
        
        # 检查二进制文件是否存在
        if [ ! -f "$CADDY_BINARY" ]; then
            error "未找到 Caddy 二进制文件"
            exit 1
        fi
        
        # 安装到系统目录（需要 root 权限）
        info "安装 Caddy 到 $CADDY_INSTALL_DIR..."
        if [ "$EUID" -eq 0 ]; then
            cp "$CADDY_BINARY" "$CADDY_INSTALL_DIR/caddy"
            chmod +x "$CADDY_INSTALL_DIR/caddy"
        else
            warn "需要 root 权限安装 Caddy，尝试使用 sudo..."
            sudo cp "$CADDY_BINARY" "$CADDY_INSTALL_DIR/caddy"
            sudo chmod +x "$CADDY_INSTALL_DIR/caddy"
        fi
    fi
    
    # 无论是否已安装，都设置 Caddyfile 符号链接
    setup_caddyfile_link
    
    success "Caddy 安装完成"
    
    # 验证安装
    if command -v caddy &> /dev/null; then
        local version=$(caddy version 2>/dev/null | head -n1 || echo "unknown")
        info "Caddy 版本: $version"
    fi
}

# 生成后端服务 systemd 文件
generate_backend_service() {
    info "生成后端服务 systemd 文件..."
    
    # 确保 tmp 目录存在
    mkdir -p "$TMP_DIR"
    
    local service_file="$TMP_DIR/jingrow-backend.service"
    local uv_dir=$(dirname "$UV_PATH")
    local env_file_line=""
    
    # 如果 .env 文件存在，使用 EnvironmentFile 引用
    if [ -f "$PROJECT_ROOT/.env" ]; then
        env_file_line="EnvironmentFile=${PROJECT_ROOT}/.env"
    fi
    
    cat > "$service_file" <<EOF
[Unit]
Description=Jingrow Backend API Service
After=network.target redis.service
Requires=redis.service

[Service]
Type=simple
User=${SERVICE_USER}
Group=${SERVICE_GROUP}
WorkingDirectory=${JINGROW_APP_DIR}
Environment="PATH=${uv_dir}:/usr/local/bin:/usr/bin:/bin"
Environment="HOME=${HOME}"
${env_file_line}
ExecStart=${UV_PATH} run python -m jingrow.app
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=jingrow-backend

# 安全设置
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF
    
    success "已生成: $service_file"
}

# 生成 Worker 服务 systemd 文件
generate_worker_service() {
    info "生成 Worker 服务 systemd 文件..."
    
    # 确保 tmp 目录存在
    mkdir -p "$TMP_DIR"
    
    local service_file="$TMP_DIR/jingrow-worker.service"
    local uv_dir=$(dirname "$UV_PATH")
    local env_file_line=""
    
    # 如果 .env 文件存在，使用 EnvironmentFile 引用
    if [ -f "$PROJECT_ROOT/.env" ]; then
        env_file_line="EnvironmentFile=${PROJECT_ROOT}/.env"
    fi
    
    cat > "$service_file" <<EOF
[Unit]
Description=Jingrow Worker Service (Dramatiq)
After=network.target redis.service
Requires=redis.service

[Service]
Type=simple
User=${SERVICE_USER}
Group=${SERVICE_GROUP}
WorkingDirectory=${JINGROW_APP_DIR}
Environment="PATH=${uv_dir}:/usr/local/bin:/usr/bin:/bin"
Environment="HOME=${HOME}"
${env_file_line}
ExecStart=${UV_PATH} run python -m jingrow.dramatiq
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=jingrow-worker

# 安全设置
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF
    
    success "已生成: $service_file"
}

# 生成 Caddy 服务 systemd 文件
generate_caddy_service() {
    info "生成 Caddy 服务 systemd 文件..."
    
    # 确保 tmp 目录存在
    mkdir -p "$TMP_DIR"
    
    local service_file="$TMP_DIR/caddy.service"
    local env_file_line=""
    
    # 如果 .env 文件存在，使用 EnvironmentFile 引用（Caddyfile 会读取环境变量）
    if [ -f "$PROJECT_ROOT/.env" ]; then
        env_file_line="EnvironmentFile=${PROJECT_ROOT}/.env"
    fi
    
    cat > "$service_file" <<EOF
[Unit]
Description=Caddy - Modern HTTP/2 web server
Documentation=https://caddyserver.com/docs/
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
User=${SERVICE_USER}
Group=${SERVICE_GROUP}
WorkingDirectory=${PROJECT_ROOT}
${env_file_line}
ExecStart=${CADDY_INSTALL_DIR}/caddy run --environ --config ${CADDY_CONFIG_DIR}/Caddyfile
ExecReload=${CADDY_INSTALL_DIR}/caddy reload --config ${CADDY_CONFIG_DIR}/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
EOF
    
    success "已生成: $service_file"
}

# 安装 systemd 服务文件
install_services() {
    # 检查是否有 --no-install 参数
    local skip_install=false
    for arg in "$@"; do
        if [ "$arg" = "--no-install" ]; then
            skip_install=true
            break
        fi
    done
    
    if [ "$skip_install" = true ]; then
        info "跳过服务安装（--no-install），服务文件已生成在 $TMP_DIR"
        return 0
    fi
    
    info "安装 systemd 服务文件..."
    
    local services=("jingrow-backend.service" "jingrow-worker.service" "caddy.service")
    
    for service in "${services[@]}"; do
        local service_file="$TMP_DIR/$service"
        local service_name=$(basename "$service")
        if [ -f "$service_file" ]; then
            info "安装 $service_name..."
            if [ "$EUID" -eq 0 ]; then
                cp "$service_file" "/etc/systemd/system/$service_name"
                chmod 644 "/etc/systemd/system/$service_name"
            else
                sudo cp "$service_file" "/etc/systemd/system/$service_name"
                sudo chmod 644 "/etc/systemd/system/$service_name"
            fi
            success "$service_name 已安装"
        else
            warn "$service_name 不存在，跳过"
        fi
    done
    
    # 重新加载 systemd
    info "重新加载 systemd..."
    if [ "$EUID" -eq 0 ]; then
        systemctl daemon-reload
    else
        sudo systemctl daemon-reload
    fi
    
    success "服务文件安装完成"
    info "使用以下命令管理服务:"
    echo "  sudo systemctl start jingrow-backend"
    echo "  sudo systemctl start jingrow-worker"
    echo "  sudo systemctl start caddy"
    echo "  sudo systemctl enable jingrow-backend jingrow-worker caddy  # 开机自启"
}

# 主函数
main() {
    info "开始生成生产环境服务文件..."
    
    # 检测架构
    detect_arch
    
    # 检查必要工具
    if ! command -v curl &> /dev/null; then
        error "需要 curl，请先安装"
        exit 1
    fi
    
    if ! command -v tar &> /dev/null; then
        error "需要 tar，请先安装"
        exit 1
    fi
    
    # 检测 uv 路径
    detect_uv_path
    
    # 检查项目目录
    if [ ! -d "$JINGROW_APP_DIR" ]; then
        error "未找到后端目录: $JINGROW_APP_DIR"
        exit 1
    fi
    
    # 安装 Caddy
    install_caddy
    
    # 生成服务文件
    generate_backend_service
    generate_worker_service
    generate_caddy_service
    
    # 安装服务（静默安装，除非指定 --no-install）
    install_services "$@"
    
    success "完成！"
    info "生成的文件（位于 $TMP_DIR）:"
    echo "  - $TMP_DIR/jingrow-backend.service"
    echo "  - $TMP_DIR/jingrow-worker.service"
    echo "  - $TMP_DIR/caddy.service"
    echo ""
    info "注意事项:"
    echo "  1. 确保已构建前端: npm run build:frontend"
    echo "  2. 确保后端依赖已安装: npm run install:backend"
    echo "  3. 确保 Redis 已安装并运行"
    echo "  4. 检查并配置 .env 文件"
    echo "  5. 修改服务文件中的用户和组（如需要）"
}

main "$@"

