#!/bin/bash
# ============================================
# Nginx 轻量监控系统 v1.1
# 基于 systemd + crontab/timer 实现
# ============================================

set -e

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

# 配置
HEALTH_CHECK_SCRIPT="/usr/local/bin/nginx_health_check.sh"
HEALTH_LOG="/var/log/nginx_health.log"
HEALTH_PORT="8088"
HEALTH_URL="http://127.0.0.1:${HEALTH_PORT}/health"
HEALTH_CONF="/etc/nginx/conf.d/health_check.conf"
OVERRIDE_DIR="/etc/systemd/system/nginx.service.d"
OVERRIDE_CONF="${OVERRIDE_DIR}/override.conf"

# 全局标志：健康检查是否可用
HEALTH_CHECK_AVAILABLE=false

# 检查root权限
check_root() {
    if [ "$EUID" -ne 0 ]; then
        echo -e "${RED}请使用 root 权限运行此脚本${NC}"
        exit 1
    fi
}

# 检查Nginx是否安装
check_nginx() {
    if ! command -v nginx >/dev/null 2>&1; then
        echo -e "${RED}错误：未检测到 Nginx，请先安装${NC}"
        exit 1
    fi
}

# 检查并安装curl
ensure_curl() {
    if ! command -v curl >/dev/null 2>&1; then
        echo "正在安装 curl..."
        if command -v apt-get >/dev/null 2>&1; then
            apt-get update && apt-get install -y curl
        elif command -v yum >/dev/null 2>&1; then
            yum install -y curl
        else
            echo -e "${RED}无法安装 curl，健康检查功能将不可用${NC}"
            return 1
        fi
    fi
    return 0
}

# 设置时区
set_timezone() {
    echo -e "${BLUE}当前时区：$(timedatectl | grep 'Time zone' | awk '{print $3}')${NC}"
    read -p "是否设置为 Asia/Hong_Kong？(y/n) [n]: " set_tz
    if [[ "$set_tz" == "y" || "$set_tz" == "Y" ]]; then
        timedatectl set-timezone Asia/Hong_Kong
        echo -e "${GREEN}时区已设置为 Asia/Hong_Kong${NC}"
    fi
}

# 配置systemd自动重启
setup_systemd_restart() {
    echo "配置 systemd 自动重启..."
    mkdir -p "$OVERRIDE_DIR"
    
    cat > "$OVERRIDE_CONF" << 'EOF'
[Unit]
StartLimitIntervalSec=0
StartLimitBurst=0

[Service]
Restart=always
RestartSec=5
EOF
    
    systemctl daemon-reload
    echo -e "${GREEN}✓ systemd 自动重启已配置（进程退出后5秒重启）${NC}"
}

# 检查端口是否被占用
check_port_available() {
    local port=$1
    if ss -tlnp | grep -q ":${port} "; then
        return 1  # 端口被占用
    fi
    return 0  # 端口可用
}

# 创建并验证健康检查端点
setup_health_endpoint() {
    echo ""
    echo -e "${BLUE}【健康检查配置】${NC}"
    
    # 检查 curl 是否可用
    if ! command -v curl >/dev/null 2>&1; then
        echo -e "${YELLOW}⚠ curl 未安装，跳过健康检查功能${NC}"
        HEALTH_CHECK_AVAILABLE=false
        return 1
    fi
    
    # 检查端口是否被占用（排除已有的健康检查配置）
    if [ ! -f "$HEALTH_CONF" ]; then
        if ! check_port_available "$HEALTH_PORT"; then
            echo -e "${YELLOW}⚠ 端口 $HEALTH_PORT 已被占用，跳过健康检查功能${NC}"
            HEALTH_CHECK_AVAILABLE=false
            return 1
        fi
    fi
    
    # 创建健康检查配置
    echo "创建健康检查端点配置..."
    cat > "$HEALTH_CONF" << EOF
server {
    listen 127.0.0.1:${HEALTH_PORT};
    server_name localhost;
    
    location /health {
        access_log off;
        default_type text/plain;
        return 200 'OK';
    }
}
EOF
    
    # 验证 Nginx 配置语法
    if ! nginx -t >/dev/null 2>&1; then
        echo -e "${RED}✗ Nginx 配置验证失败${NC}"
        rm -f "$HEALTH_CONF"
        HEALTH_CHECK_AVAILABLE=false
        return 1
    fi
    
    # 重载 Nginx
    systemctl reload nginx
    sleep 2
    
    # 测试健康端点是否可用
    echo "测试健康端点..."
    if curl -sf --max-time 5 "$HEALTH_URL" >/dev/null 2>&1; then
        echo -e "${GREEN}✓ 健康端点可用：$HEALTH_URL${NC}"
        HEALTH_CHECK_AVAILABLE=true
        return 0
    else
        echo -e "${RED}✗ 健康端点不可用，跳过健康检查功能${NC}"
        rm -f "$HEALTH_CONF"
        systemctl reload nginx 2>/dev/null || true
        HEALTH_CHECK_AVAILABLE=false
        return 1
    fi
}

# 创建健康检查脚本
create_health_script() {
    echo "创建健康检查脚本..."
    
    cat > "$HEALTH_CHECK_SCRIPT" << EOF
#!/bin/bash
HEALTH_URL="${HEALTH_URL}"
LOG_FILE="${HEALTH_LOG}"
MAX_LOG_LINES=1000

# 检查Nginx是否响应
if ! curl -sf --max-time 5 "\$HEALTH_URL" >/dev/null 2>&1; then
    # 二次确认
    sleep 2
    if ! curl -sf --max-time 5 "\$HEALTH_URL" >/dev/null 2>&1; then
        echo "\$(date '+%Y-%m-%d %H:%M:%S'): Nginx 无响应，执行重启" >> "\$LOG_FILE"
        systemctl restart nginx
        
        # 检查重启结果
        sleep 3
        if curl -sf --max-time 5 "\$HEALTH_URL" >/dev/null 2>&1; then
            echo "\$(date '+%Y-%m-%d %H:%M:%S'): Nginx 重启成功" >> "\$LOG_FILE"
        else
            echo "\$(date '+%Y-%m-%d %H:%M:%S'): Nginx 重启失败，需人工介入" >> "\$LOG_FILE"
        fi
    fi
fi

# 日志轮转（保留最近1000行）
if [ -f "\$LOG_FILE" ] && [ \$(wc -l < "\$LOG_FILE") -gt \$MAX_LOG_LINES ]; then
    tail -n \$MAX_LOG_LINES "\$LOG_FILE" > "\${LOG_FILE}.tmp"
    mv "\${LOG_FILE}.tmp" "\$LOG_FILE"
fi
EOF
    
    chmod +x "$HEALTH_CHECK_SCRIPT"
    echo -e "${GREEN}✓ 健康检查脚本已创建${NC}"
}

# 方案A：使用 crontab
setup_crontab() {
    echo ""
    echo "配置 crontab 定时任务..."
    
    # 移除旧的相关任务
    crontab -l 2>/dev/null | grep -v "nginx_health_check.sh" | grep -v "systemctl reload nginx" > /tmp/crontab.tmp || true
    
    # 添加健康检查（每分钟）- 仅当健康检查可用时
    if [ "$HEALTH_CHECK_AVAILABLE" = true ]; then
        echo "* * * * * $HEALTH_CHECK_SCRIPT" >> /tmp/crontab.tmp
        echo -e "${GREEN}✓ 已添加健康检查任务（每分钟）${NC}"
    fi
    
    # 添加定时重载
    read -p "是否添加定时重载？(y/n) [y]: " add_reload
    add_reload=${add_reload:-y}
    
    if [[ "$add_reload" == "y" || "$add_reload" == "Y" ]]; then
        read -p "重载时间（默认 7,19 表示7点和19点）: " reload_hours
        reload_hours=${reload_hours:-7,19}
        echo "0 $reload_hours * * * systemctl reload nginx" >> /tmp/crontab.tmp
        echo -e "${GREEN}✓ 已添加定时重载任务${NC}"
    fi
    
    crontab /tmp/crontab.tmp
    rm -f /tmp/crontab.tmp
    
    echo ""
    echo "当前 crontab 任务："
    crontab -l
}

# 方案B：使用 systemd timer
setup_systemd_timer() {
    echo ""
    echo "配置 systemd timer..."
    
    # 健康检查 - 仅当健康检查可用时
    if [ "$HEALTH_CHECK_AVAILABLE" = true ]; then
        cat > /etc/systemd/system/nginx-health.service << EOF
[Unit]
Description=Nginx Health Check

[Service]
Type=oneshot
ExecStart=$HEALTH_CHECK_SCRIPT
EOF
        
        cat > /etc/systemd/system/nginx-health.timer << 'EOF'
[Unit]
Description=Nginx Health Check Timer

[Timer]
OnBootSec=60
OnUnitActiveSec=60

[Install]
WantedBy=timers.target
EOF
        
        systemctl daemon-reload
        systemctl enable --now nginx-health.timer
        echo -e "${GREEN}✓ 健康检查 timer 已启用（每分钟）${NC}"
    fi
    
    # 定时重载
    read -p "是否添加定时重载？(y/n) [y]: " add_reload
    add_reload=${add_reload:-y}
    
    if [[ "$add_reload" == "y" || "$add_reload" == "Y" ]]; then
        read -p "重载时间（默认 07:00 和 19:00）确认？(y/n) [y]: " confirm_time
        confirm_time=${confirm_time:-y}
        
        cat > /etc/systemd/system/nginx-reload.service << 'EOF'
[Unit]
Description=Nginx Reload
After=nginx.service

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl reload nginx
EOF
        
        cat > /etc/systemd/system/nginx-reload.timer << 'EOF'
[Unit]
Description=Nginx Reload Timer

[Timer]
OnCalendar=*-*-* 07:00:00
OnCalendar=*-*-* 19:00:00
Persistent=true

[Install]
WantedBy=timers.target
EOF
        
        systemctl daemon-reload
        systemctl enable --now nginx-reload.timer
        echo -e "${GREEN}✓ 定时重载 timer 已启用${NC}"
    fi
}

# 安装函数
install_monitor() {
    echo ""
    echo -e "${BLUE}====================================================${NC}"
    echo -e "${BLUE}       Nginx 轻量监控系统 v1.1 - 安装向导${NC}"
    echo -e "${BLUE}====================================================${NC}"
    echo ""
    
    check_nginx
    ensure_curl
    
    # 设置时区
    set_timezone
    echo ""
    
    # 配置systemd自动重启（必装）
    setup_systemd_restart
    echo ""
    
    # 尝试配置健康检查端点
    setup_health_endpoint
    
    # 如果健康检查可用，创建检查脚本
    if [ "$HEALTH_CHECK_AVAILABLE" = true ]; then
        create_health_script
    fi
    
    echo ""
    
    # 选择定时方案
    echo -e "${BLUE}【定时任务配置】${NC}"
    echo "请选择定时任务方案："
    echo "  1) crontab（传统方式，简单直观）"
    echo "  2) systemd timer（现代方式，日志集成）"
    echo ""
    read -p "请选择 (1/2) [1]: " timer_choice
    timer_choice=${timer_choice:-1}
    
    case $timer_choice in
        1) setup_crontab ;;
        2) setup_systemd_timer ;;
        *) setup_crontab ;;
    esac
    
    # 重启Nginx应用配置
    systemctl restart nginx
    
    echo ""
    echo -e "${GREEN}====================================================${NC}"
    echo -e "${GREEN}✅ 安装完成！${NC}"
    echo -e "${GREEN}====================================================${NC}"
    echo ""
    echo "已配置功能："
    echo -e "  ${GREEN}✓${NC} systemd 自动重启（进程退出后5秒重启）"
    if [ "$HEALTH_CHECK_AVAILABLE" = true ]; then
        echo -e "  ${GREEN}✓${NC} 健康检查（每分钟检测假死）"
        echo -e "  ${GREEN}✓${NC} 健康端点：$HEALTH_URL"
        echo -e "  ${GREEN}✓${NC} 日志文件：$HEALTH_LOG"
    else
        echo -e "  ${YELLOW}✗${NC} 健康检查（未启用）"
    fi
    echo ""
    echo "验证命令："
    echo "  systemctl show nginx -p Restart,RestartUSec"
    if [ "$HEALTH_CHECK_AVAILABLE" = true ]; then
        echo "  curl $HEALTH_URL"
    fi
    if [[ "$timer_choice" == "1" ]]; then
        echo "  crontab -l"
    else
        echo "  systemctl list-timers --all | grep nginx"
    fi
    echo ""
}

# 卸载函数
uninstall_monitor() {
    echo ""
    echo -e "${YELLOW}正在卸载 Nginx 监控系统...${NC}"
    echo ""
    
    # 停止并删除 systemd timer
    systemctl stop nginx-health.timer 2>/dev/null || true
    systemctl disable nginx-health.timer 2>/dev/null || true
    systemctl stop nginx-reload.timer 2>/dev/null || true
    systemctl disable nginx-reload.timer 2>/dev/null || true
    
    rm -f /etc/systemd/system/nginx-health.service
    rm -f /etc/systemd/system/nginx-health.timer
    rm -f /etc/systemd/system/nginx-reload.service
    rm -f /etc/systemd/system/nginx-reload.timer
    
    # 删除 systemd override
    rm -rf "$OVERRIDE_DIR"
    
    # 清理 crontab
    crontab -l 2>/dev/null | grep -v "nginx_health_check.sh" | grep -v "systemctl reload nginx" | crontab - 2>/dev/null || true
    
    # 删除健康检查脚本
    rm -f "$HEALTH_CHECK_SCRIPT"
    
    # 删除健康端点配置
    rm -f "$HEALTH_CONF"
    nginx -t >/dev/null 2>&1 && systemctl reload nginx
    
    systemctl daemon-reload
    
    echo ""
    echo -e "${GREEN}✅ 卸载完成${NC}"
    echo -e "${YELLOW}注意：日志文件 $HEALTH_LOG 已保留，可手动删除${NC}"
    echo ""
}

# 查看状态
show_status() {
    echo ""
    echo -e "${BLUE}====================================================${NC}"
    echo -e "${BLUE}                   系统状态${NC}"
    echo -e "${BLUE}====================================================${NC}"
    echo ""
    
    # 时区
    echo -e "${YELLOW}【时区】${NC}"
    echo "  $(date)"
    echo ""
    
    # Nginx 状态
    echo -e "${YELLOW}【Nginx 服务】${NC}"
    if systemctl is-active nginx >/dev/null 2>&1; then
        echo -e "  状态: ${GREEN}运行中${NC}"
    else
        echo -e "  状态: ${RED}已停止${NC}"
    fi
    echo "  重启策略: $(systemctl show nginx -p Restart --value 2>/dev/null || echo '未配置')"
    echo "  重启延迟: $(systemctl show nginx -p RestartUSec --value 2>/dev/null || echo '未配置')"
    echo ""
    
    # 健康检查
    echo -e "${YELLOW}【健康检查】${NC}"
    if [ -f "$HEALTH_CHECK_SCRIPT" ]; then
        echo -e "  脚本: ${GREEN}已安装${NC}"
    else
        echo -e "  脚本: ${YELLOW}未安装${NC}"
    fi
    
    if [ -f "$HEALTH_CONF" ]; then
        echo -e "  配置: ${GREEN}已存在${NC}"
    else
        echo -e "  配置: ${YELLOW}未配置${NC}"
    fi
    
    if command -v curl >/dev/null 2>&1 && curl -sf --max-time 2 "$HEALTH_URL" >/dev/null 2>&1; then
        echo -e "  端点: ${GREEN}正常 ($HEALTH_URL)${NC}"
    else
        echo -e "  端点: ${YELLOW}不可用${NC}"
    fi
    echo ""
    
    # 定时任务
    echo -e "${YELLOW}【定时任务】${NC}"
    
    local has_timer=false
    
    # crontab
    if crontab -l 2>/dev/null | grep -q "nginx"; then
        echo "  crontab:"
        crontab -l 2>/dev/null | grep "nginx" | sed 's/^/    /'
        has_timer=true
    fi
    
    # systemd timer
    if systemctl is-active nginx-health.timer >/dev/null 2>&1; then
        echo -e "  nginx-health.timer: ${GREEN}活动${NC}"
        has_timer=true
    fi
    if systemctl is-active nginx-reload.timer >/dev/null 2>&1; then
        echo -e "  nginx-reload.timer: ${GREEN}活动${NC}"
        has_timer=true
    fi
    
    if [ "$has_timer" = false ]; then
        echo -e "  ${YELLOW}无定时任务${NC}"
    fi
    echo ""
    
    # 最近日志
    echo -e "${YELLOW}【健康检查日志】${NC}"
    if [ -f "$HEALTH_LOG" ]; then
        local line_count=$(wc -l < "$HEALTH_LOG")
        echo "  文件: $HEALTH_LOG ($line_count 行)"
        echo "  最近5条记录："
        tail -5 "$HEALTH_LOG" 2>/dev/null | sed 's/^/    /' || echo "    (无记录)"
    else
        echo -e "  ${YELLOW}无日志文件（正常运行时不产生日志）${NC}"
    fi
    echo ""
}

# 测试健康检查
test_health() {
    echo ""
    echo -e "${BLUE}测试健康检查...${NC}"
    echo ""
    
    echo "1. 测试健康端点："
    if command -v curl >/dev/null 2>&1; then
        echo -n "   $HEALTH_URL -> "
        local result=$(curl -sf --max-time 3 "$HEALTH_URL" 2>&1)
        if [ $? -eq 0 ]; then
            echo -e "${GREEN}$result${NC}"
        else
            echo -e "${RED}[FAIL] 端点不可用${NC}"
        fi
    else
        echo -e "   ${RED}curl 未安装${NC}"
    fi
    echo ""
    
    echo "2. 测试健康检查脚本："
    if [ -x "$HEALTH_CHECK_SCRIPT" ]; then
        echo "   执行: $HEALTH_CHECK_SCRIPT"
        $HEALTH_CHECK_SCRIPT
        echo -e "   ${GREEN}[完成]${NC}"
    else
        echo -e "   ${YELLOW}脚本不存在或无执行权限${NC}"
    fi
    echo ""
    
    echo "3. 模拟故障测试（可选）："
    echo -e "   ${YELLOW}注意：将强制杀死 Nginx 进程模拟崩溃${NC}"
    read -p "   是否执行？(y/n) [n]: " test_restart
    if [[ "$test_restart" == "y" || "$test_restart" == "Y" ]]; then
        echo "   强制杀死 Nginx 进程（模拟崩溃）..."
        local kill_time=$(date '+%H:%M:%S')
        pkill -9 nginx
        echo "   杀死时间: $kill_time"
        echo "   等待 systemd 自动重启（最多 20 秒）..."
        
        # 循环检测，最多等20秒
        local wait_count=0
        while [ $wait_count -lt 20 ]; do
            sleep 2
            wait_count=$((wait_count + 2))
            if systemctl is-active nginx >/dev/null 2>&1; then
                local restart_time=$(date '+%H:%M:%S')
                echo -e "   ${GREEN}✓ Nginx 已自动重启${NC}"
                echo "   重启时间: $restart_time（等待了 ${wait_count} 秒）"
                echo -e "   ${GREEN}✓ systemd Restart=always 配置生效！${NC}"
                return
            fi
            echo "   等待中... ${wait_count}秒"
        done
        
        echo -e "   ${RED}✗ Nginx 未在 20 秒内自动重启${NC}"
        echo "   请检查配置: systemctl show nginx -p Restart,RestartUSec"
        echo "   尝试手动启动..."
        systemctl start nginx
    fi
    echo ""
}

# 查看日志
view_logs() {
    echo ""
    if [ -f "$HEALTH_LOG" ]; then
        echo -e "${BLUE}健康检查日志 ($HEALTH_LOG)：${NC}"
        echo "按 Ctrl+C 退出"
        echo ""
        sleep 1
        tail -f "$HEALTH_LOG"
    else
        echo -e "${YELLOW}日志文件不存在：$HEALTH_LOG${NC}"
        echo "健康检查尚未触发任何事件（这是正常的，只有异常时才记录）"
    fi
}

# 主菜单
main_menu() {
    check_root
    
    while true; do
        clear
        echo -e "${BLUE}====================================================${NC}"
        echo -e "${BLUE}        Nginx 轻量监控系统 v1.1${NC}"
        echo -e "${BLUE}====================================================${NC}"
        echo ""
        echo "  1) 安装监控系统"
        echo "  2) 卸载监控系统"
        echo "  3) 查看状态"
        echo "  4) 测试健康检查"
        echo "  5) 查看实时日志"
        echo "  6) 退出"
        echo ""
        echo -e "${BLUE}====================================================${NC}"
        read -p "请选择 (1-6): " choice
        
        case $choice in
            1)
                install_monitor
                read -p "按回车继续..."
                ;;
            2)
                uninstall_monitor
                read -p "按回车继续..."
                ;;
            3)
                show_status
                read -p "按回车继续..."
                ;;
            4)
                test_health
                read -p "按回车继续..."
                ;;
            5)
                view_logs
                ;;
            6)
                echo ""
                echo "再见！"
                exit 0
                ;;
            *)
                echo -e "${RED}无效选项${NC}"
                sleep 1
                ;;
        esac
    done
}

# 运行主菜单
main_menu
