#!/bin/bash

# tcping 自动安装脚本
# 作者: Auto Generated Script
# 版本: 1.0

set -e  # 遇到错误立即退出

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

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

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

# 检查命令是否存在
check_command() {
    if command -v "$1" >/dev/null 2>&1; then
        return 0
    else
        return 1
    fi
}

# 检查是否为 root 用户
check_root() {
    if [ "$EUID" -ne 0 ]; then
        log_error "请使用 root 权限运行此脚本"
        echo "使用方法: sudo $0"
        exit 1
    fi
}

# 步骤1: 更新系统包列表
step1_update_packages() {
    log_info "步骤 1/5: 更新系统包列表..."
    
    if apt update; then
        log_success "系统包列表更新完成"
        return 0
    else
        log_error "系统包列表更新失败，请检查网络连接和软件源配置"
        return 1
    fi
}

# 步骤2: 安装依赖包
step2_install_dependencies() {
    log_info "步骤 2/5: 安装依赖包 (golang, git, make)..."
    
    # 检查是否已安装
    local missing_deps=()
    
    if ! check_command go; then
        missing_deps+=("golang")
    fi
    
    if ! check_command git; then
        missing_deps+=("git")
    fi
    
    if ! check_command make; then
        missing_deps+=("make")
    fi
    
    if [ ${#missing_deps[@]} -eq 0 ]; then
        log_success "所有依赖包已安装"
        return 0
    fi
    
    log_info "需要安装的依赖包: ${missing_deps[*]}"
    
    if apt install -y golang git make; then
        log_success "依赖包安装完成"
        
        # 验证安装结果
        if check_command go && check_command git && check_command make; then
            log_success "依赖包验证通过"
            log_info "Go 版本: $(go version)"
            return 0
        else
            log_error "依赖包安装验证失败"
            return 1
        fi
    else
        log_error "依赖包安装失败，请检查网络连接和软件源"
        return 1
    fi
}

# 步骤3: 下载源码
step3_download_source() {
    log_info "步骤 3/5: 下载 tcping 源码..."
    
    local src_dir="/usr/local/src"
    local tcping_dir="$src_dir/tcping"
    
    # 创建源码目录
    if [ ! -d "$src_dir" ]; then
        mkdir -p "$src_dir"
    fi
    
    cd "$src_dir" || {
        log_error "无法进入目录: $src_dir"
        return 1
    }
    
    # 如果目录已存在，先删除
    if [ -d "$tcping_dir" ]; then
        log_warning "tcping 目录已存在，正在删除旧版本..."
        rm -rf "$tcping_dir"
    fi
    
    # 克隆仓库
    if git clone https://github.com/cloverstd/tcping.git; then
        log_success "源码下载完成"
        
        # 验证下载结果
        if [ -d "$tcping_dir" ] && [ -f "$tcping_dir/go.mod" ]; then
            log_success "源码完整性验证通过"
            return 0
        else
            log_error "源码下载不完整"
            return 1
        fi
    else
        log_error "源码下载失败，请检查网络连接"
        return 1
    fi
}

# 步骤4: 编译项目
step4_compile_project() {
    log_info "步骤 4/5: 编译 tcping 项目..."
    
    local tcping_dir="/usr/local/src/tcping"
    
    cd "$tcping_dir" || {
        log_error "无法进入目录: $tcping_dir"
        return 1
    }
    
    # 首先尝试直接 make
    log_info "尝试直接编译..."
    if make; then
        log_success "编译成功"
    else
        log_warning "直接编译失败，尝试修复依赖..."
        
        # 修复 Go modules
        log_info "执行 go mod tidy..."
        if ! go mod tidy; then
            log_error "go mod tidy 执行失败"
            return 1
        fi
        
        log_info "执行 go mod vendor..."
        if ! go mod vendor; then
            log_error "go mod vendor 执行失败"
            return 1
        fi
        
        log_info "重新尝试编译..."
        if ! make; then
            log_error "编译失败，请检查编译环境"
            return 1
        fi
        
        log_success "修复依赖后编译成功"
    fi
    
    # 验证编译结果
    if [ -f "tcping" ]; then
        log_success "编译产物验证通过: tcping"
        return 0
    elif [ -f "build/tcping" ]; then
        log_success "编译产物验证通过: build/tcping"
        return 0
    else
        log_error "未找到编译产物，编译可能失败"
        return 1
    fi
}

# 步骤5: 安装到系统路径
step5_install_binary() {
    log_info "步骤 5/5: 安装 tcping 到系统路径..."
    
    local tcping_dir="/usr/local/src/tcping"
    local target_path="/usr/local/bin/tcping"
    
    cd "$tcping_dir" || {
        log_error "无法进入目录: $tcping_dir"
        return 1
    }
    
    # 查找编译产物
    local binary_path=""
    if [ -f "tcping" ]; then
        binary_path="tcping"
    elif [ -f "build/tcping" ]; then
        binary_path="build/tcping"
    else
        log_error "未找到 tcping 二进制文件"
        return 1
    fi
    
    # 备份现有版本
    if [ -f "$target_path" ]; then
        log_warning "发现已安装的 tcping，正在备份..."
        mv "$target_path" "${target_path}.backup.$(date +%Y%m%d_%H%M%S)"
    fi
    
    # 安装二进制文件
    if cp "$binary_path" "$target_path"; then
        log_success "二进制文件复制完成"
    else
        log_error "二进制文件复制失败"
        return 1
    fi
    
    # 设置执行权限
    if chmod +x "$target_path"; then
        log_success "执行权限设置完成"
    else
        log_error "执行权限设置失败"
        return 1
    fi
    
    # 验证安装结果
    if [ -x "$target_path" ]; then
        log_success "安装验证通过"
        log_info "tcping 版本信息:"
        if "$target_path" -h >/dev/null 2>&1; then
            log_success "tcping 可正常运行"
            return 0
        else
            log_warning "tcping 安装完成，但运行测试未通过"
            return 0
        fi
    else
        log_error "安装验证失败"
        return 1
    fi
}

# 清理函数
cleanup() {
    log_info "清理临时文件..."
    # 可选择是否保留源码目录
    read -p "是否删除源码目录 /usr/local/src/tcping? (y/N): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        rm -rf /usr/local/src/tcping
        log_success "源码目录已清理"
    else
        log_info "源码目录保留在: /usr/local/src/tcping"
    fi
}

# 主函数
main() {
    echo "======================================"
    echo "       tcping 自动安装脚本"
    echo "======================================"
    echo
    
    # 检查 root 权限
    check_root
    
    # 显示系统信息
    log_info "系统信息: $(lsb_release -d 2>/dev/null | cut -f2 || echo "Unknown Linux")"
    log_info "开始安装流程..."
    echo
    
    # 执行安装步骤
    if ! step1_update_packages; then
        log_error "步骤 1 失败，安装中止"
        exit 1
    fi
    echo
    
    if ! step2_install_dependencies; then
        log_error "步骤 2 失败，安装中止"
        exit 1
    fi
    echo
    
    if ! step3_download_source; then
        log_error "步骤 3 失败，安装中止"
        exit 1
    fi
    echo
    
    if ! step4_compile_project; then
        log_error "步骤 4 失败，安装中止"
        exit 1
    fi
    echo
    
    if ! step5_install_binary; then
        log_error "步骤 5 失败，安装中止"
        exit 1
    fi
    echo
    
    # 安装完成
    echo "======================================"
    log_success "tcping 安装完成！"
    echo "======================================"
    
    # 显示使用方法
    echo
    log_info "使用方法:"
    echo "  tcping -h                    # 查看帮助"
    echo "  tcping google.com 80         # 测试 TCP 连通性"
    echo "  tcping -c 4 baidu.com 443    # 测试 4 次"
    echo
    
    # 测试安装
    log_info "快速测试:"
    if /usr/local/bin/tcping -h >/dev/null 2>&1; then
        echo "  ✓ tcping 命令可用"
    else
        echo "  ✗ tcping 命令测试失败"
    fi
    
    # 清理选项
    echo
    cleanup
    
    log_success "安装脚本执行完毕！"
}

# 信号处理
trap 'log_error "脚本被中断"; exit 130' INT TERM

# 执行主函数
main "$@"
