#!/bin/bash

# ============================================
# LinkMaster 节点端 systemd 启动脚本
# 用于 systemd 服务，直接运行二进制文件
# ============================================

set -e

# 脚本目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

# 配置
BINARY_NAME="agent"
BACKEND_URL="${BACKEND_URL:-http://localhost:8080}"

# 检查二进制文件是否存在且有效
check_binary() {
    if [ -f "$BINARY_NAME" ] && [ -x "$BINARY_NAME" ] && [ -s "$BINARY_NAME" ]; then
        # 验证二进制文件类型（Linux 应该是 ELF 文件）
        if command -v file > /dev/null 2>&1; then
            local file_type=$(file "$BINARY_NAME" 2>/dev/null || echo "")
            if [ -n "$file_type" ] && echo "$file_type" | grep -qi "ELF"; then
                return 0
            fi
        else
            # 如果没有 file 命令，至少检查文件大小（应该大于 1MB）
            local file_size=$(stat -c%s "$BINARY_NAME" 2>/dev/null || stat -f%z "$BINARY_NAME" 2>/dev/null || echo "0")
            if [ "$file_size" -gt 1048576 ]; then
                return 0
            fi
        fi
    fi
    return 1
}

# 拉取最新源码并编译
update_and_build() {
    # 如果二进制文件已存在且有效，跳过编译
    if check_binary; then
        echo "二进制文件已存在，跳过编译步骤"
        return 0
    fi
    
    # 检查是否在 Git 仓库中
    if [ ! -d ".git" ]; then
        echo "错误: 不在 Git 仓库中，无法更新代码" >&2
        return 1
    fi
    
    # 配置 Git safe.directory，解决所有权问题
    CURRENT_DIR=$(pwd)
    git config --global --add safe.directory "$CURRENT_DIR" 2>/dev/null || true
    
    # 拉取最新代码
    if git pull 2>&1 > /dev/null; then
        echo "代码更新完成"
    fi
    
    # 确保 Go 在 PATH 中（systemd 可能没有设置 PATH）
    if [ -d "/usr/local/go/bin" ] && ! echo "$PATH" | grep -q "/usr/local/go/bin"; then
        export PATH="/usr/local/go/bin:$PATH"
    fi
    
    # 检查 Go 环境
    if ! command -v go > /dev/null 2>&1; then
        echo "错误: 未找到 Go 环境，无法编译" >&2
        echo "PATH: $PATH" >&2
        echo "请确保 Go 已安装: /usr/local/go/bin 或系统 PATH 中包含 go 命令" >&2
        exit 1
    fi
    
    # 检查是否有 vendor 目录
    local use_vendor=false
    if [ -d "./vendor" ] && [ -f "./vendor/modules.txt" ]; then
        use_vendor=true
        echo "使用 vendor 目录编译（无需网络连接）"
    fi
    
    # 更新依赖（仅在非 vendor 模式下，并设置超时避免卡住）
    if [ "$use_vendor" != "true" ]; then
        echo "更新 Go 依赖..."
        # 使用 timeout 命令设置超时（30秒），如果系统没有 timeout 命令则直接执行
        if command -v timeout > /dev/null 2>&1; then
            timeout 30 go mod download 2>&1 > /dev/null || {
                echo "警告: 依赖更新失败或超时，尝试继续编译" >&2
            }
        else
            # 如果没有 timeout 命令，直接执行（可能卡住，但至少能工作）
            go mod download 2>&1 > /dev/null || {
                echo "警告: 依赖更新失败，尝试继续编译" >&2
            }
        fi
    fi
    
    # 编译
    ARCH=$(uname -m)
    case $ARCH in
        x86_64)
            ARCH="amd64"
            ;;
        aarch64|arm64)
            ARCH="arm64"
            ;;
        *)
            ARCH="amd64"
            ;;
    esac
    
    # 构建编译命令
    local build_cmd="GOOS=linux GOARCH=${ARCH} CGO_ENABLED=0 go build -buildvcs=false -ldflags=\"-w -s\""
    if [ "$use_vendor" = "true" ]; then
        build_cmd="$build_cmd -mod=vendor"
    fi
    build_cmd="$build_cmd -o \"$BINARY_NAME\" ./cmd/agent"
    
    echo "开始编译（架构: ${ARCH}）..."
    if eval "$build_cmd" 2>&1; then
        if [ -f "$BINARY_NAME" ] && [ -s "$BINARY_NAME" ]; then
            chmod +x "$BINARY_NAME"
            echo "编译成功"
            return 0
        else
            echo "错误: 编译失败，未生成二进制文件" >&2
            return 1
        fi
    else
        echo "错误: 编译失败" >&2
        return 1
    fi
}

# 检查并更新/编译
if ! check_binary; then
    update_and_build
fi

# 设置环境变量
export BACKEND_URL="$BACKEND_URL"

# 直接运行二进制文件（systemd 会管理进程）
exec ./"$BINARY_NAME"

