#!/usr/bin/env bash
#
# speedtest 服务安装/管理脚本
# 用法:
#   sudo ./install.sh install    — 安装/更新服务
#   sudo ./install.sh uninstall  — 卸载服务
#   sudo ./install.sh start      — 启动服务
#   sudo ./install.sh stop       — 停止服务
#   sudo ./install.sh restart    — 重启服务
#   sudo ./install.sh status     — 查看服务状态
#

source /etc/profile
source ~/.bashrc

set -euo pipefail

# ======================== 配置区 ========================
SERVICE_NAME="speedtest"
SERVICE_USER="speedtest"
SERVICE_DESC="SpeedTest - Go 网速测试（延迟/下载/上传 + 排行）"

# 目录
INSTALL_DIR="/opt/speedtest"           # 程序安装目录
DATA_DIR="/srv/speedtest"              # 数据目录（SQLite 数据库）
CONFIG_DIR="/etc/speedtest"            # 配置文件目录
LOG_DIR="/var/log/speedtest"           # 日志目录

# Git 仓库
GIT_REPO="https://git.lmve.net/dsh/speedtest.git"
GIT_BRANCH="main"

# 编译临时目录
BUILD_DIR="/tmp/speedtest_build"

# systemd 服务文件路径
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"

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

info()  { echo -e "${BLUE}[INFO]${NC} $*"; }
ok()    { echo -e "${GREEN}[OK]${NC} $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }

# ======================== 前置检查 ========================
check_root() {
    if [[ $EUID -ne 0 ]]; then
        error "此脚本需要 root 权限运行，请使用 sudo"
    fi
}

# ======================== 用户管理 ========================
ensure_user() {
    if id "${SERVICE_USER}" &>/dev/null; then
        ok "用户 ${SERVICE_USER} 已存在"
    else
        info "创建系统用户 ${SERVICE_USER} ..."
        useradd -r -s /usr/sbin/nologin -d "${INSTALL_DIR}" -c "${SERVICE_DESC}" "${SERVICE_USER}"
        ok "用户 ${SERVICE_USER} 创建成功"
    fi
}

# ======================== 目录管理 ========================
ensure_dirs() {
    info "检查并创建关键目录 ..."

    # 安装目录（含模板子目录结构）
    mkdir -p "${INSTALL_DIR}/internal/web/templates"
    # 配置目录
    mkdir -p "${CONFIG_DIR}"
    # 数据目录
    mkdir -p "${DATA_DIR}"
    # 日志目录
    mkdir -p "${LOG_DIR}"

    # 设置所有权（每次安装都强制修正，避免旧版遗留权限问题）
    chown -R "${SERVICE_USER}:${SERVICE_USER}" "${INSTALL_DIR}"
    chown -R "${SERVICE_USER}:${SERVICE_USER}" "${DATA_DIR}"
    chown -R "${SERVICE_USER}:${SERVICE_USER}" "${LOG_DIR}"
    chown -R "${SERVICE_USER}:${SERVICE_USER}" "${CONFIG_DIR}"

    # 确保目录可写
    chmod 755 "${CONFIG_DIR}" "${DATA_DIR}" "${LOG_DIR}" "${INSTALL_DIR}"

    ok "目录结构就绪"
}

# ======================== 编译 ========================
build_binary() {
    info "拉取最新代码 ..."
    if [[ -d "${BUILD_DIR}/.git" ]]; then
        cd "${BUILD_DIR}"
        git fetch --all
        git reset --hard "origin/${GIT_BRANCH}"
        info "代码已更新到最新"
    else
        rm -rf "${BUILD_DIR}"
        git clone -b "${GIT_BRANCH}" "${GIT_REPO}" "${BUILD_DIR}"
        cd "${BUILD_DIR}"
        info "代码克隆完成"
    fi

    info "编译 Go 项目（CGO 已启用，SQLite 依赖） ..."
    CGO_ENABLED=1 go build -ldflags="-s -w" -o speedtest .
    ok "编译完成: ${BUILD_DIR}/speedtest"
}

# ======================== 部署文件 ========================
deploy_files() {
    info "部署文件到 ${INSTALL_DIR} ..."

    # 停止服务（如果正在运行），避免替换正在使用的二进制
    if systemctl is-active --quiet "${SERVICE_NAME}" 2>/dev/null; then
        info "停止运行中的服务 ..."
        systemctl stop "${SERVICE_NAME}"
    fi

    # 复制二进制
    cp -f "${BUILD_DIR}/speedtest" "${INSTALL_DIR}/speedtest"
    chmod 755 "${INSTALL_DIR}/speedtest"

    # 复制模板文件（目录结构: internal/web/templates/*.html）
    cp -f "${BUILD_DIR}/internal/web/templates/"*.html "${INSTALL_DIR}/internal/web/templates/"

    # 复制 ip2region 地区库（离线 GeoIP 数据）
    mkdir -p "${INSTALL_DIR}/data"
    cp -f "${BUILD_DIR}/data/ip2region_v4.xdb" "${INSTALL_DIR}/data/ip2region_v4.xdb"

    # 配置文件由程序首次启动时自动生成 + 缺失项自动补全，脚本不干预
    if [[ -f "${CONFIG_DIR}/speedtest.toml" ]]; then
        info "保留现有配置文件: ${CONFIG_DIR}/speedtest.toml"
    else
        info "配置文件不存在，程序首次启动将自动生成"
    fi

    # 设置安装目录所有权
    chown -R "${SERVICE_USER}:${SERVICE_USER}" "${INSTALL_DIR}"

    ok "文件部署完成"
}

# ======================== systemd 服务 ========================
install_service() {
    info "创建 systemd 服务文件 ..."

    cat > "${SERVICE_FILE}" <<EOF
[Unit]
Description=${SERVICE_DESC}
After=network.target
Wants=network.target

[Service]
Type=simple
User=${SERVICE_USER}
Group=${SERVICE_USER}
WorkingDirectory=${INSTALL_DIR}
ExecStart=${INSTALL_DIR}/speedtest
ExecReload=/bin/kill -HUP \$MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

# 日志输出到 journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=${SERVICE_NAME}

# 安全加固：专用低权用户运行
# ProtectSystem=strict/full 会阻止写入 /etc 和 /opt 等目录，
# 导致配置文件和 unix socket 无法创建，得不偿失
ProtectHome=true
NoNewPrivileges=true

# 环境变量
Environment=GIN_MODE=release

[Install]
WantedBy=multi-user.target
EOF

    chmod 644 "${SERVICE_FILE}"
    systemctl daemon-reload
    ok "systemd 服务文件已创建"
}

# ======================== 安装主流程 ========================
do_install() {
    info "========== 安装 ${SERVICE_NAME} =========="

    # 1. 检查依赖
    check_root
    command -v git &>/dev/null || error "需要 git，请先安装"
    command -v go &>/dev/null  || error "需要 go，请先安装"
    command -v gcc &>/dev/null || error "需要 gcc（CGO/SQLite 编译依赖），请先安装"

    # 2. 创建用户
    ensure_user

    # 3. 创建目录
    ensure_dirs

    # 4. 拉取代码并编译
    build_binary

    # 5. 部署文件
    deploy_files

    # 6. 安装服务
    install_service

    # 7. 启动并设置开机自启
    info "启动服务 ..."
    systemctl start "${SERVICE_NAME}"
    systemctl enable "${SERVICE_NAME}"

    sleep 1
    if systemctl is-active --quiet "${SERVICE_NAME}"; then
        ok "服务启动成功！"
    else
        error "服务启动失败，请检查日志: journalctl -u ${SERVICE_NAME} -n 50"
    fi

    echo ""
    info "========== 安装完成 =========="
    echo "  程序目录:   ${INSTALL_DIR}"
    echo "  配置文件:   ${CONFIG_DIR}/speedtest.toml"
    echo "  数据目录:   ${DATA_DIR}"
    echo "  日志查看:   journalctl -u ${SERVICE_NAME} -f"
    echo "  服务管理:   systemctl {start|stop|restart|status} ${SERVICE_NAME}"
    echo ""
    echo "  监听地址:   unix socket ${INSTALL_DIR}/web.sock（由 Caddy 反代）"
    echo "  访问地址:   https://speedtest.lmve.net"
    echo ""
    warn "  若 Caddy 尚未配置反代，请编辑 /etc/caddy/Caddyfile 添加:"
    echo ""
    echo "    speedtest.lmve.net {"
    echo "        reverse_proxy unix//opt/speedtest/web.sock {"
    echo "            header_up X-Real-IP {remote_host}"
    echo "            header_up Host {host}"
    echo "        }"
    echo "    }"
    echo ""
}

# ======================== 卸载 ========================
do_uninstall() {
    info "========== 卸载 ${SERVICE_NAME} =========="
    check_root

    # 停止服务
    if systemctl is-active --quiet "${SERVICE_NAME}" 2>/dev/null; then
        systemctl stop "${SERVICE_NAME}"
        info "服务已停止"
    fi

    # 禁用开机自启
    if systemctl is-enabled --quiet "${SERVICE_NAME}" 2>/dev/null; then
        systemctl disable "${SERVICE_NAME}"
        info "已禁用开机自启"
    fi

    # 删除服务文件
    if [[ -f "${SERVICE_FILE}" ]]; then
        rm -f "${SERVICE_FILE}"
        systemctl daemon-reload
        info "服务文件已删除"
    fi

    # 询问是否删除数据
    echo ""
    warn "以下目录包含运行数据，是否删除？"
    echo "  [1] ${INSTALL_DIR}  (程序文件+模板)"
    echo "  [2] ${DATA_DIR}     (数据库)"
    echo "  [3] ${CONFIG_DIR}   (配置文件)"
    echo "  [4] ${LOG_DIR}      (日志)"
    echo "  [0] 全部保留（默认）"
    echo "  [a] 全部删除"
    echo ""
    read -rp "请选择 [0/a/组合如 14]: " choice

    case "${choice:-0}" in
        0)
            info "保留所有数据目录"
            ;;
        a|A)
            rm -rf "${INSTALL_DIR}" "${DATA_DIR}" "${CONFIG_DIR}" "${LOG_DIR}"
            info "所有数据目录已删除"
            ;;
        *)
            [[ "${choice}" == *1* ]] && rm -rf "${INSTALL_DIR}" && info "已删除 ${INSTALL_DIR}"
            [[ "${choice}" == *2* ]] && rm -rf "${DATA_DIR}" && info "已删除 ${DATA_DIR}"
            [[ "${choice}" == *3* ]] && rm -rf "${CONFIG_DIR}" && info "已删除 ${CONFIG_DIR}"
            [[ "${choice}" == *4* ]] && rm -rf "${LOG_DIR}" && info "已删除 ${LOG_DIR}"
            ;;
    esac

    # 删除用户（如果没有其他依赖）
    if id "${SERVICE_USER}" &>/dev/null; then
        read -rp "是否删除系统用户 ${SERVICE_USER}？[y/N]: " del_user
        if [[ "${del_user}" =~ ^[Yy]$ ]]; then
            userdel "${SERVICE_USER}"
            info "系统用户 ${SERVICE_USER} 已删除"
        fi
    fi

    # 清理编译目录
    rm -rf "${BUILD_DIR}"

    ok "卸载完成"
}

# ======================== 服务控制 ========================
do_start() {
    check_root
    systemctl start "${SERVICE_NAME}"
    sleep 1
    if systemctl is-active --quiet "${SERVICE_NAME}"; then
        ok "服务已启动"
    else
        error "服务启动失败，查看日志: journalctl -u ${SERVICE_NAME} -n 50"
    fi
}

do_stop() {
    check_root
    systemctl stop "${SERVICE_NAME}"
    ok "服务已停止"
}

do_restart() {
    check_root
    systemctl restart "${SERVICE_NAME}"
    sleep 1
    if systemctl is-active --quiet "${SERVICE_NAME}"; then
        ok "服务已重启"
    else
        error "服务重启失败，查看日志: journalctl -u ${SERVICE_NAME} -n 50"
    fi
}

do_status() {
    systemctl status "${SERVICE_NAME}" --no-pager || true
}

# ======================== 入口 ========================
case "${1:-}" in
    install)           do_install           ;;
    uninstall)         do_uninstall         ;;
    start)             do_start             ;;
    stop)              do_stop              ;;
    restart)           do_restart           ;;
    status)            do_status            ;;
    *)
        echo "用法: sudo $0 {install|uninstall|start|stop|restart|status}"
        echo ""
        echo "  install          — 完整安装/更新（拉代码+编译+部署+启动+开机自启）"
        echo "  uninstall        — 卸载服务（可选保留数据）"
        echo "  start            — 启动服务"
        echo "  stop             — 停止服务"
        echo "  restart          — 重启服务"
        echo "  status           — 查看服务状态"
        exit 1
        ;;
esac
