#!/bin/bash

#==============================================================================
# Rocky Linux 交互式系统配置脚本
# 功能：镜像源、GitHub加速、SELinux、防火墙、dotnet、Redis、MySQL、Caddy
#==============================================================================

set -e

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

# 日志文件
LOG_FILE="/var/log/rocky_setup_$(date +%Y%m%d_%H%M%S).log"

#==============================================================================
# 工具函数
#==============================================================================

# 打印信息
print_info() {
    echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
}

# 分隔线
print_separator() {
    echo -e "${BLUE}================================================================${NC}"
}

# 确认提示
confirm() {
    read -p "$(echo -e ${YELLOW}"$1 (y/n): "${NC})" choice
    case "$choice" in 
        y|Y|yes|YES ) return 0;;
        * ) return 1;;
    esac
}

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

#==============================================================================
# 1. 配置国内镜像源加速
#==============================================================================

configure_mirror() {
    print_separator
    print_info "开始配置国内镜像源..."
    
    # 备份原有源
    if [ ! -f /etc/yum.repos.d/Rocky-BaseOS.repo.bak ]; then
        cp -r /etc/yum.repos.d /etc/yum.repos.d.backup_$(date +%Y%m%d)
        print_success "已备份原有源配置"
    fi
    
    # 选择镜像源
    echo "请选择镜像源："
    echo "1) 阿里云"
    echo "2) 清华大学"
    echo "3) 中科大"
    read -p "请输入选项 (1-3): " mirror_choice
    
    case $mirror_choice in
        1)
            MIRROR_URL="mirrors.aliyun.com"
            print_info "使用阿里云镜像源"
            ;;
        2)
            MIRROR_URL="mirrors.tuna.tsinghua.edu.cn"
            print_info "使用清华大学镜像源"
            ;;
        3)
            MIRROR_URL="mirrors.ustc.edu.cn"
            print_info "使用中科大镜像源"
            ;;
        *)
            print_warning "无效选项，使用阿里云镜像源"
            MIRROR_URL="mirrors.aliyun.com"
            ;;
    esac
    
    # 获取Rocky Linux版本
    ROCKY_VERSION=$(grep -oP '(?<=^VERSION_ID=).+' /etc/os-release | tr -d '"')
    
    # 配置BaseOS
    cat > /etc/yum.repos.d/Rocky-BaseOS.repo <<EOF
[baseos]
name=Rocky Linux \$releasever - BaseOS
baseurl=https://${MIRROR_URL}/rockylinux/\$releasever/BaseOS/\$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-\$releasever
EOF

    # 配置AppStream
    cat > /etc/yum.repos.d/Rocky-AppStream.repo <<EOF
[appstream]
name=Rocky Linux \$releasever - AppStream
baseurl=https://${MIRROR_URL}/rockylinux/\$releasever/AppStream/\$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-\$releasever
EOF

    # 配置Extras
    cat > /etc/yum.repos.d/Rocky-Extras.repo <<EOF
[extras]
name=Rocky Linux \$releasever - Extras
baseurl=https://${MIRROR_URL}/rockylinux/\$releasever/extras/\$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-\$releasever
EOF

    # 配置EPEL
    cat > /etc/yum.repos.d/epel.repo <<EOF
[epel]
name=Extra Packages for Enterprise Linux \$releasever - \$basearch
baseurl=https://${MIRROR_URL}/epel/\$releasever/Everything/\$basearch/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-\$releasever
EOF

    # 清除缓存并生成新缓存
    dnf clean all
    dnf makecache
    
    print_success "镜像源配置完成"
}

#==============================================================================
# 2. 配置GitHub加速
#==============================================================================

configure_github_acceleration() {
    print_separator
    print_info "开始配置GitHub加速..."
    
    # 备份hosts
    cp /etc/hosts /etc/hosts.backup_$(date +%Y%m%d)
    
    # 添加GitHub加速hosts
    cat >> /etc/hosts <<EOF

# GitHub加速配置 - $(date)
140.82.113.4    github.com
199.232.69.194  github.global.ssl.fastly.net
185.199.108.153 assets-cdn.github.com
185.199.109.153 assets-cdn.github.com
185.199.110.153 assets-cdn.github.com
185.199.111.153 assets-cdn.github.com
199.232.96.133  raw.githubusercontent.com
199.232.96.133  gist.githubusercontent.com
199.232.96.133  cloud.githubusercontent.com
199.232.96.133  camo.githubusercontent.com
EOF

    # 配置Git代理（可选）
    if confirm "是否配置Git HTTP代理？"; then
        read -p "请输入代理地址 (例如: http://127.0.0.1:7890): " git_proxy
        git config --global http.proxy "$git_proxy"
        git config --global https.proxy "$git_proxy"
        print_success "Git代理配置完成: $git_proxy"
    fi
    
    print_success "GitHub加速配置完成"
}

#==============================================================================
# 3. 配置SELinux安全模式
#==============================================================================

configure_selinux() {
    print_separator
    print_info "开始配置SELinux..."
    
    echo "请选择SELinux模式："
    echo "1) Enforcing (强制模式)"
    echo "2) Permissive (宽容模式)"
    echo "3) Disabled (禁用)"
    read -p "请输入选项 (1-3): " selinux_choice
    
    case $selinux_choice in
        1)
            setenforce 1
            sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
            print_success "SELinux设置为Enforcing模式"
            ;;
        2)
            setenforce 0
            sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config
            print_success "SELinux设置为Permissive模式"
            ;;
        3)
            setenforce 0
            sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
            print_warning "SELinux已禁用（需要重启生效）"
            ;;
        *)
            print_warning "无效选项，保持当前设置"
            ;;
    esac
    
    print_info "当前SELinux状态: $(getenforce)"
}

#==============================================================================
# 4. 配置防火墙端口
#==============================================================================

configure_firewall() {
    print_separator
    print_info "开始配置防火墙..."
    
    # 安装并启动firewalld
    if ! systemctl is-active --quiet firewalld; then
        dnf install -y firewalld
        systemctl enable firewalld
        systemctl start firewalld
        print_success "Firewalld已安装并启动"
    fi
    
    # 常用端口配置
    echo "选择要开放的端口："
    echo "1) HTTP (80)"
    echo "2) HTTPS (443)"
    echo "3) SSH (22)"
    echo "4) Redis (6379)"
    echo "5) MySQL (3306)"
    echo "6) 自定义端口"
    echo "7) 全部开放以上端口"
    read -p "请输入选项 (多个选项用空格分隔): " -a port_choices
    
    for choice in "${port_choices[@]}"; do
        case $choice in
            1)
                firewall-cmd --permanent --add-service=http
                print_success "已开放HTTP端口(80)"
                ;;
            2)
                firewall-cmd --permanent --add-service=https
                print_success "已开放HTTPS端口(443)"
                ;;
            3)
                firewall-cmd --permanent --add-service=ssh
                print_success "已开放SSH端口(22)"
                ;;
            4)
                firewall-cmd --permanent --add-port=6379/tcp
                print_success "已开放Redis端口(6379)"
                ;;
            5)
                firewall-cmd --permanent --add-port=3306/tcp
                print_success "已开放MySQL端口(3306)"
                ;;
            6)
                read -p "请输入自定义端口号: " custom_port
                firewall-cmd --permanent --add-port=${custom_port}/tcp
                print_success "已开放端口${custom_port}"
                ;;
            7)
                firewall-cmd --permanent --add-service=http
                firewall-cmd --permanent --add-service=https
                firewall-cmd --permanent --add-service=ssh
                firewall-cmd --permanent --add-port=6379/tcp
                firewall-cmd --permanent --add-port=3306/tcp
                print_success "已开放所有常用端口"
                ;;
        esac
    done
    
    # 重载防火墙
    firewall-cmd --reload
    print_success "防火墙配置已生效"
    
    # 显示已开放的端口
    print_info "当前开放的端口和服务："
    firewall-cmd --list-all
}

#==============================================================================
# 5. 安装.NET 8.0 SDK
#==============================================================================

install_dotnet() {
    print_separator
    print_info "开始安装.NET 8.0 SDK..."
    
    # 添加Microsoft软件源
    dnf install -y dotnet-sdk-8.0
    
    if [ $? -ne 0 ]; then
        print_info "通过微软官方脚本安装..."
        curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 8.0
        
        # 配置环境变量
        echo 'export DOTNET_ROOT=$HOME/.dotnet' >> ~/.bashrc
        echo 'export PATH=$PATH:$HOME/.dotnet:$HOME/.dotnet/tools' >> ~/.bashrc
        source ~/.bashrc
    fi
    
    # 验证安装
    dotnet --version
    print_success ".NET 8.0 SDK安装完成"
}

#==============================================================================
# 6. 本地安装Redis
#==============================================================================

install_redis() {
    print_separator
    print_info "开始安装Redis..."
    
    # 安装Redis
    dnf install -y redis
    
    # 配置Redis
    read -p "请输入Redis密码（留空则不设置密码）: " redis_password
    
    if [ -n "$redis_password" ]; then
        sed -i "s/# requirepass foobared/requirepass $redis_password/" /etc/redis/redis.conf
        print_success "Redis密码已设置"
    fi
    
    # 配置为监听所有接口（可选）
    if confirm "是否允许Redis远程访问？"; then
        sed -i 's/bind 127.0.0.1/bind 0.0.0.0/' /etc/redis/redis.conf
        print_warning "Redis已配置为允许远程访问，请确保设置了密码"
    fi
    
    # 启动Redis
    systemctl enable redis
    systemctl start redis
    
    print_success "Redis安装并启动完成"
    
    # 保存密码到文件
    if [ -n "$redis_password" ]; then
        echo "Redis密码: $redis_password" >> /root/service_passwords.txt
        chmod 600 /root/service_passwords.txt
    fi
}

#==============================================================================
# 7. 本地安装MySQL 8.0
#==============================================================================

install_mysql() {
    print_separator
    print_info "开始安装MySQL 8.0..."
    
    # 安装MySQL
    dnf install -y mysql-server
    
    # 启动MySQL
    systemctl enable mysqld
    systemctl start mysqld
    
    # 等待MySQL完全启动
    sleep 5
    
    print_info "配置MySQL..."
    
    # 设置root密码
    read -sp "请输入MySQL root密码: " mysql_password
    echo
    read -sp "请再次输入MySQL root密码: " mysql_password_confirm
    echo
    
    if [ "$mysql_password" != "$mysql_password_confirm" ]; then
        print_error "两次输入的密码不一致"
        return 1
    fi
    
    # 使用mysql_secure_installation的命令配置
    mysql -u root <<EOF
ALTER USER 'root'@'localhost' IDENTIFIED BY '$mysql_password';
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
FLUSH PRIVILEGES;
EOF
    
    # 允许远程访问（可选）
    if confirm "是否允许root用户远程访问MySQL？"; then
        mysql -u root -p"$mysql_password" <<EOF
CREATE USER 'root'@'%' IDENTIFIED BY '$mysql_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EOF
        print_warning "已允许root远程访问，请注意安全"
    fi
    
    print_success "MySQL 8.0安装完成"
    
    # 保存密码
    echo "MySQL root密码: $mysql_password" >> /root/service_passwords.txt
    chmod 600 /root/service_passwords.txt
    
    print_info "MySQL密码已保存到 /root/service_passwords.txt"
}

#==============================================================================
# 8. 本地安装Caddy 2
#==============================================================================

install_caddy() {
    print_separator
    print_info "开始安装Caddy 2..."
    
    # 安装依赖
    dnf install -y yum-plugin-copr
    
    # 添加Caddy COPR仓库
    dnf copr enable -y @caddy/caddy
    
    # 安装Caddy
    dnf install -y caddy
    
    # 创建基本配置
    cat > /etc/caddy/Caddyfile <<EOF
# Caddy 配置文件
# 默认配置示例

# 示例：反向代理到本地应用
# example.com {
#     reverse_proxy localhost:5000
# }

# 示例：静态文件服务
# example.com {
#     root * /var/www/html
#     file_server
# }
EOF
    
    # 启动Caddy
    systemctl enable caddy
    systemctl start caddy
    
    print_success "Caddy 2安装完成"
    print_info "配置文件位置: /etc/caddy/Caddyfile"
    print_info "请根据需要修改配置后重启Caddy: systemctl restart caddy"
}

#==============================================================================
# 9. 各服务状态检查
#==============================================================================

check_services_status() {
    print_separator
    print_info "检查各服务状态..."
    echo
    
    # 服务列表
    services=("redis" "mysqld" "caddy" "firewalld")
    
    for service in "${services[@]}"; do
        if systemctl is-active --quiet "$service"; then
            print_success "$service: 运行中"
            echo "  状态详情:"
            systemctl status "$service" --no-pager -l | head -3 | sed 's/^/    /'
        else
            print_warning "$service: 未运行"
        fi
        echo
    done
    
    # 检查.NET
    print_info ".NET SDK 版本:"
    if command -v dotnet &> /dev/null; then
        dotnet --version | sed 's/^/    /'
        print_success ".NET SDK: 已安装"
    else
        print_warning ".NET SDK: 未安装"
    fi
    echo
    
    # 检查SELinux
    print_info "SELinux状态: $(getenforce)"
    echo
    
    # 检查防火墙端口
    print_info "防火墙开放的端口:"
    firewall-cmd --list-ports | sed 's/^/    /'
    firewall-cmd --list-services | sed 's/^/    服务: /'
    echo
    
    # 检查Redis连接
    if systemctl is-active --quiet redis; then
        print_info "Redis连接测试:"
        redis-cli ping | sed 's/^/    /'
    fi
    echo
    
    # 检查MySQL连接
    if systemctl is-active --quiet mysqld; then
        print_info "MySQL版本:"
        mysql --version | sed 's/^/    /'
    fi
    echo
    
    print_separator
}

#==============================================================================
# 主菜单
#==============================================================================

show_menu() {
    clear
    print_separator
    echo -e "${GREEN}        Rocky Linux 交互式系统配置脚本${NC}"
    print_separator
    echo "1)  配置国内镜像源加速"
    echo "2)  配置GitHub加速"
    echo "3)  配置SELinux安全模式"
    echo "4)  配置防火墙端口"
    echo "5)  安装.NET 8.0 SDK"
    echo "6)  本地安装Redis"
    echo "7)  本地安装MySQL 8.0"
    echo "8)  本地安装Caddy 2"
    echo "9)  各服务状态检查"
    echo "10) 一键安装所有服务"
    echo "0)  退出"
    print_separator
}

# 一键安装
install_all() {
    print_info "开始一键安装所有服务..."
    
    configure_mirror
    configure_github_acceleration
    configure_selinux
    configure_firewall
    install_dotnet
    install_redis
    install_mysql
    install_caddy
    check_services_status
    
    print_success "所有服务安装完成！"
    print_info "密码信息已保存到: /root/service_passwords.txt"
}

#==============================================================================
# 主程序
#==============================================================================

main() {
    check_root
    
    print_info "日志文件: $LOG_FILE"
    
    while true; do
        show_menu
        read -p "请选择操作 (0-10): " choice
        
        case $choice in
            1) configure_mirror ;;
            2) configure_github_acceleration ;;
            3) configure_selinux ;;
            4) configure_firewall ;;
            5) install_dotnet ;;
            6) install_redis ;;
            7) install_mysql ;;
            8) install_caddy ;;
            9) check_services_status ;;
            10) install_all ;;
            0) 
                print_info "感谢使用，再见！"
                exit 0
                ;;
            *)
                print_error "无效选项，请重新选择"
                ;;
        esac
        
        echo
        read -p "按Enter键继续..." 
    done
}

# 运行主程序
main
