#!/bin/bash

################################################################################
# FF AI Workspace 生产环境初始化脚本
################################################################################
#
# 【用途】
# 此脚本用于首次部署时初始化全新的生产服务器
# ⚠️  只在首次部署时运行一次！
#
# 【主要功能】
# - 安装系统软件（Docker, Node.js, PM2, Nginx, Certbot）
# - 配置系统环境（防火墙、开机自启等）
# - 创建目录结构
# - 生成配置模板和自动化脚本
#
# 【执行顺序】
# 1. setup-production.sh                        ← 首次运行（本脚本）⭐
# 2. deploy-unified.sh production up --all     ← 启动 Docker 服务
# 3. deploy-unified.sh production deploy       ← 部署应用
#
# 【后续更新】
# 代码更新时只需运行: bash scripts/deploy/deploy-unified.sh production deploy
#
################################################################################

set -e

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

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

# 检查是否为 root 用户
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本需要 root 权限运行"
        log_info "请使用: sudo bash setup-production.sh"
        exit 1
    fi
}

# 检测操作系统
detect_os() {
    log_step "检测操作系统..."
    
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS=$ID
        VERSION=$VERSION_ID
        log_info "检测到系统: $PRETTY_NAME"
    else
        log_error "无法检测操作系统"
        exit 1
    fi
    
    if [[ "$OS" != "ubuntu" ]]; then
        log_warn "此脚本针对 Ubuntu 20.04+ 优化，其他系统可能需要调整"
        read -p "是否继续? [y/N] " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            exit 1
        fi
    fi
}

# 更新系统
update_system() {
    log_step "更新系统包..."
    apt update
    apt upgrade -y
    apt install -y curl wget git vim build-essential
}

# 安装 Docker
install_docker() {
    log_step "安装 Docker..."
    
    if command -v docker &> /dev/null; then
        log_info "Docker 已安装: $(docker --version)"
        return
    fi
    
    # 安装依赖
    apt install -y \
        ca-certificates \
        gnupg \
        lsb-release
    
    # 添加 Docker GPG 密钥
    mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    
    # 添加 Docker 仓库
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    # 安装 Docker
    apt update
    apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
    # 启动 Docker
    systemctl start docker
    systemctl enable docker
    
    # 添加当前用户到 docker 组
    if [ -n "$SUDO_USER" ]; then
        usermod -aG docker $SUDO_USER
        log_info "已将用户 $SUDO_USER 添加到 docker 组"
    fi
    
    log_info "Docker 安装完成: $(docker --version)"
    log_info "Docker Compose: $(docker compose version)"
}

# 安装 Node.js
install_nodejs() {
    log_step "安装 Node.js 20..."
    
    if command -v node &> /dev/null; then
        NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
        if [ "$NODE_VERSION" -ge 20 ]; then
            log_info "Node.js 已安装: $(node -v)"
            return
        else
            log_warn "Node.js 版本过低 ($(node -v))，正在升级..."
        fi
    fi
    
    # 使用 NodeSource 仓库
    curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
    apt install -y nodejs
    
    log_info "Node.js 安装完成: $(node -v)"
    log_info "npm 版本: $(npm -v)"
}

# 安装 PM2
install_pm2() {
    log_step "安装 PM2..."
    
    if command -v pm2 &> /dev/null; then
        log_info "PM2 已安装: $(pm2 -v)"
        return
    fi
    
    npm install -g pm2
    
    # 设置 PM2 开机自启
    pm2 startup systemd -u ${SUDO_USER:-$USER} --hp /home/${SUDO_USER:-$USER}
    
    log_info "PM2 安装完成: $(pm2 -v)"
}

# 安装 Nginx
install_nginx() {
    log_step "安装 Nginx..."
    
    if command -v nginx &> /dev/null; then
        log_info "Nginx 已安装: $(nginx -v 2>&1)"
        return
    fi
    
    apt install -y nginx
    systemctl start nginx
    systemctl enable nginx
    
    log_info "Nginx 安装完成"
}

# 安装 ssl-cert（提供 snakeoil 默认证书）
# Ubuntu 24.04 minimal 默认不装 ssl-cert，导致后续配 nginx 默认 site 时
# /etc/ssl/certs/ssl-cert-snakeoil.pem 缺失 → nginx -t fail。详见 #273 评论 3。
install_ssl_cert() {
    log_step "安装 ssl-cert (snakeoil 默认证书)..."
    if dpkg -s ssl-cert >/dev/null 2>&1; then
        log_info "ssl-cert 已安装"
        return
    fi
    apt install -y ssl-cert
    log_info "ssl-cert 安装完成（snakeoil 证书已自动生成）"
}

# 配置 nginx 443 default_server return 444 兜底 site
# 防止删 site 后 unknown server_name 落到第一个 443 server block 错路由（详见 #273 评论 3 坑 5）。
# 退役域名时未配套 DNS 删 + 兜底 site，三步缺一就有误跳风险。
setup_default_nginx_site() {
    log_step "配置 nginx 443 default_server 兜底 site..."
    local repo_template_dir="$(dirname "$(readlink -f "$0")")/../../docker/nginx/sites"
    local source_conf="$repo_template_dir/000-default-https-444.conf"
    local site_path=/etc/nginx/sites-available/000-default-https-444
    local enabled_path=/etc/nginx/sites-enabled/000-default-https-444

    if [ ! -f "$source_conf" ]; then
        log_warn "找不到 nginx 模板 $source_conf，跳过兜底 site 配置"
        return
    fi

    install -m 644 "$source_conf" "$site_path"
    log_info "兜底 site 已就位：$site_path（源：$source_conf）"

    if [ ! -L "$enabled_path" ]; then
        ln -s "$site_path" "$enabled_path"
        log_info "symlink 已创建：$enabled_path"
    fi

    if nginx -t >/dev/null 2>&1; then
        systemctl reload nginx
        log_info "✅ nginx 已重载，443 default 兜底生效"
    else
        log_warn "nginx -t 失败，未 reload；手工 nginx -t 查错"
    fi
}

# 安装 Certbot
install_certbot() {
    log_step "安装 Certbot (Let's Encrypt)..."
    
    if command -v certbot &> /dev/null; then
        log_info "Certbot 已安装"
        return
    fi
    
    apt install -y certbot python3-certbot-nginx
    
    log_info "Certbot 安装完成"
}

# 配置防火墙
setup_firewall() {
    log_step "配置防火墙..."
    
    if ! command -v ufw &> /dev/null; then
        apt install -y ufw
    fi
    
    # 配置防火墙规则
    ufw --force enable
    ufw default deny incoming
    ufw default allow outgoing
    
    # 允许必要端口
    ufw allow 22/tcp comment 'SSH'
    ufw allow 80/tcp comment 'HTTP'
    ufw allow 443/tcp comment 'HTTPS'
    
    log_info "防火墙配置完成"
    ufw status
}

# 配置 git credential（opt-in：只在 GITEA_USER + GITEA_TOKEN 都显式传时跑）
# 新机器 git clone 后改 anon URL 再跑 deploy.sh 会撞 "could not read Username" fatal
# （deploy.sh 内部 git pull 私有仓库需要凭据）。详见 #273 坑 2。
# 不无条件配——明文 token 写 ~/.git-credentials 在多用户机有泄漏风险，必须用户明示 opt-in。
configure_git_credential() {
    if [ -z "${GITEA_USER:-}" ] || [ -z "${GITEA_TOKEN:-}" ]; then
        log_info "未传 GITEA_USER + GITEA_TOKEN，跳过 git credential 配置"
        log_info "如需启用：GITEA_USER=<user> GITEA_TOKEN=<token> bash setup-production.sh"
        return
    fi

    log_step "配置 git credential（opt-in）..."
    local target_user="${SUDO_USER:-$USER}"
    local target_home
    target_home=$(getent passwd "$target_user" | cut -d: -f6)
    local cred_file="$target_home/.git-credentials"

    sudo -u "$target_user" git config --global credential.helper store
    # umask 077 + sudo -u 已保证 600 mode + 正确 owner，无需后续 chmod/chown
    sudo -u "$target_user" bash -c "umask 077 && echo 'http://${GITEA_USER}:${GITEA_TOKEN}@43.130.59.228' > '$cred_file'"

    log_warn "已写 $cred_file（mode 600，明文 token），请勿在多用户机长期保留"
    log_info "✅ git credential 已配置（user=${GITEA_USER}）"
}

# 创建目录结构
setup_directories() {
    log_step "创建目录结构..."
    
    PROJECT_DIR=$(pwd)
    
    # 创建日志目录
    mkdir -p "$PROJECT_DIR/logs"
    
    # 创建上传目录
    mkdir -p "$PROJECT_DIR/uploads"
    
    # 创建备份目录
    mkdir -p "$PROJECT_DIR/backups"
    
    # 创建 Docker 数据目录
    mkdir -p "$PROJECT_DIR/docker-data/postgres"
    mkdir -p "$PROJECT_DIR/docker-data/redis"
    mkdir -p "$PROJECT_DIR/docker-data/minio"
    mkdir -p "$PROJECT_DIR/docker-data/prometheus"
    mkdir -p "$PROJECT_DIR/docker-data/grafana"
    
    # 设置权限
    if [ -n "$SUDO_USER" ]; then
        chown -R $SUDO_USER:$SUDO_USER "$PROJECT_DIR"
    fi
    
    log_info "目录结构创建完成"
}

# 生成环境变量模板
generate_env_templates() {
    log_step "生成环境变量模板..."
    
    PROJECT_DIR=$(pwd)
    
    # 生成随机密钥
    JWT_SECRET=$(openssl rand -base64 32)
    AUDIT_SECRET=$(openssl rand -base64 32)
    DB_PASSWORD=$(openssl rand -base64 24)
    POSTGRES_PASSWORD=$(openssl rand -base64 24)
    
    # 后端环境变量
    cat > "$PROJECT_DIR/backend/.env.production.template" << EOF
# FF AI Workspace Backend 生产环境配置
# 使用前请复制为 .env.production 并修改相应值

# 应用配置
NODE_ENV=production
PORT=6011
APP_NAME="FF AI Workspace"

# 数据库配置（Docker 容器）
DATABASE_URL="postgresql://ffoa_user:${DB_PASSWORD}@localhost:6001/ffoa_production"

# Redis 配置（Docker 容器）
REDIS_HOST=localhost
REDIS_PORT=6002

# JWT 配置（详见 docs/standards/09-iam-security.md §2.2）
JWT_SECRET=${JWT_SECRET}
JWT_ACCESS_TTL=30d
JWT_REFRESH_TTL=30d

# CORS 配置
CORS_ORIGIN=https://your-domain.com

# 上传配置
UPLOAD_DIR=${PROJECT_DIR}/uploads
MAX_FILE_SIZE=10485760

# Temporal 配置（Docker 容器）
TEMPORAL_ADDRESS=localhost:6003
TEMPORAL_NAMESPACE=production
TEMPORAL_TASK_QUEUE=ffoa-task-queue

# MinIO / S3 配置（Docker 容器）
S3_ENDPOINT=http://localhost:6006
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
S3_BUCKET=ffoa-attachments

# 审计日志配置
AUDIT_SECRET_KEY=${AUDIT_SECRET}

# 日志配置
LOG_LEVEL=info
EOF

    # 前端环境变量
    cat > "$PROJECT_DIR/frontend/.env.production.template" << EOF
# FF AI Workspace Frontend 生产环境配置
# 使用前请复制为 .env.production 并修改相应值

# API 配置（通过 Nginx 代理）
NEXT_PUBLIC_API_URL=/api/v1

# 应用 URL
NEXT_PUBLIC_APP_URL=https://your-domain.com

# 环境
NODE_ENV=production
EOF

    # Docker Compose 环境变量
    cat > "$PROJECT_DIR/.env.docker" << EOF
# Docker Compose 环境变量
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
POSTGRES_USER=ffoa_user
POSTGRES_DB=ffoa_production
EOF

    log_info "环境变量模板已生成:"
    log_info "  - backend/.env.production.template"
    log_info "  - frontend/.env.production.template"
    log_info "  - .env.docker"
    log_warn "请复制模板文件并根据实际情况修改"
}

# 创建数据库备份脚本
create_backup_script() {
    log_step "创建数据库备份脚本..."
    
    PROJECT_DIR=$(pwd)
    
    cat > /usr/local/bin/backup-ffoa-db.sh << EOF
#!/bin/bash
# FF AI Workspace 数据库备份脚本

BACKUP_DIR=${PROJECT_DIR}/backups
DATE=\$(date +%Y%m%d_%H%M%S)
CONTAINER_NAME=ffoa-postgres

# 创建备份目录
mkdir -p \$BACKUP_DIR

# 备份数据库（从 Docker 容器）
docker exec \$CONTAINER_NAME pg_dump -U ffoa_user ffoa_production | gzip > \$BACKUP_DIR/ffoa_\$DATE.sql.gz

# 删除 7 天前的备份
find \$BACKUP_DIR -name "ffoa_*.sql.gz" -mtime +7 -delete

echo "数据库备份完成: \$BACKUP_DIR/ffoa_\$DATE.sql.gz"
EOF

    chmod +x /usr/local/bin/backup-ffoa-db.sh
    
    # 创建 cron 任务（每天凌晨 2 点备份）
    (crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/backup-ffoa-db.sh >> ${PROJECT_DIR}/logs/backup.log 2>&1") | crontab -
    
    log_info "数据库备份脚本已创建: /usr/local/bin/backup-ffoa-db.sh"
    log_info "自动备份任务已设置（每天 02:00）"
}

# 显示下一步操作
show_next_steps() {
    PROJECT_DIR=$(pwd)
    
    echo ""
    echo "=========================================="
    log_info "🎉 生产环境初始化完成！"
    echo "=========================================="
    echo ""
    echo "📋 下一步操作："
    echo ""
    echo "1️⃣  配置环境变量："
    echo "   cd ${PROJECT_DIR}"
    echo "   cp backend/.env.production.template backend/.env.production"
    echo "   cp frontend/.env.production.template frontend/.env.production"
    echo "   vim backend/.env.production  # 修改配置"
    echo "   vim frontend/.env.production # 修改配置"
    echo ""
    echo "2️⃣  启动 Docker 服务："
    echo "   bash scripts/deploy/deploy-unified.sh production up --all"
    echo ""
    echo "3️⃣  部署应用："
    echo "   bash scripts/deploy/deploy-unified.sh production deploy"
    echo ""
    echo "   或手动执行："
    echo "   cd backend && npm ci --production && npm run build && cd .."
    echo "   cd frontend && npm ci --production && npm run build && cd .."
    echo ""
    echo "4️⃣  运行数据库迁移："
    echo "   cd backend && npx prisma migrate deploy && cd .."
    echo ""
    echo "5️⃣  启动应用（PM2）："
    echo "   pm2 start ecosystem.config.js"
    echo "   pm2 save"
    echo ""
    echo "6️⃣  配置 Nginx："
    echo "   sudo vim /etc/nginx/sites-available/ffoa"
    echo "   # 复制文档中的 Nginx 配置"
    echo "   sudo ln -s /etc/nginx/sites-available/ffoa /etc/nginx/sites-enabled/"
    echo "   sudo nginx -t"
    echo "   sudo systemctl reload nginx"
    echo ""
    echo "7️⃣  配置 SSL："
    echo "   sudo certbot --nginx -d your-domain.com"
    echo ""
    echo "=========================================="
    echo "📚 详细文档："
    echo "   ${PROJECT_DIR}/docs/DEPLOYMENT_COMPLETE_GUIDE.md"
    echo "=========================================="
    echo ""
    
    log_warn "注意：如果添加了用户到 docker 组，需要重新登录才能生效"
}

# 主函数
main() {
    echo ""
    echo "=========================================="
    echo "  FF AI Workspace 生产环境初始化"
    echo "  版本: 2.0"
    echo "  架构: Docker + PM2 + Nginx"
    echo "=========================================="
    echo ""
    
    check_root
    detect_os
    
    log_info "开始安装..."
    echo ""
    
    update_system
    install_docker
    install_nodejs
    install_pm2
    install_nginx
    install_ssl_cert
    setup_default_nginx_site
    install_certbot
    setup_firewall
    configure_git_credential
    setup_directories
    generate_env_templates
    create_backup_script
    
    show_next_steps
}

# 运行主函数
main

