#!/bin/bash

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"
}

# 显示帮助信息
show_help() {
    echo "AIOps All-in-One 打包脚本"
    echo
    echo "用法: $0 [选项]"
    echo
    echo "选项:"
    echo "  --force     强制重新打包，即使版本已存在"
    echo "  --help     显示此帮助信息"
    echo
    echo "示例:"
    echo "  $0              # 正常打包，跳过已存在的版本"
    echo "  $0 --force      # 强制重新打包"
    echo
}

# 解析命令行参数
FORCE_PACKAGE=false
if [[ "$1" == "--force" ]]; then
    FORCE_PACKAGE=true
    log_info "强制重新打包模式"
elif [[ "$1" == "--help" || "$1" == "-h" ]]; then
    show_help
    exit 0
fi

# 获取当前目录和版本
CURRENT_DIR=$(pwd)
VERSION=$(cat config/VERSION 2>/dev/null || echo "1.0.0")
ARTIFACT_DIR="artifact/$VERSION"

log_info "开始打包 AIOps All-in-One 安装包 v$VERSION"

# 检查必要文件
log_info "检查必要文件..."
if [[ ! -f "config/VERSION" ]]; then
    log_error "VERSION 文件不存在"
    exit 1
fi

if [[ ! -f "config/checklist" ]]; then
    log_error "checklist 文件不存在"
    exit 1
fi

# 检查是否已存在该版本
if [[ -d "$ARTIFACT_DIR" && "$FORCE_PACKAGE" == "false" ]]; then
    log_info "检查版本 $VERSION 是否已存在..."
    
    # 检查 version.json 是否存在
    if [[ -f "$ARTIFACT_DIR/version.json" ]]; then
        log_info "找到已存在的版本信息文件"
        
        # 检查是否所有组件文件都存在
        missing_files=0
        existing_components=0
        
        # 解析已存在的 version.json 来检查文件
        if command -v jq &> /dev/null; then
            # 使用 jq 解析
            while IFS= read -r component; do
                existing_components=$((existing_components + 1))
                # 查找对应的 tar 文件
                found_file=false
                for file in "$ARTIFACT_DIR/${component}-"*.tar.gz; do
                    if [[ -f "$file" ]]; then
                        found_file=true
                        break
                    fi
                done
                if [[ "$found_file" == "false" ]]; then
                    missing_files=$((missing_files + 1))
                    log_warning "  缺少文件: $component"
                fi
            done < <(jq -r '.artifact_list | keys[]' "$ARTIFACT_DIR/version.json" 2>/dev/null)
        else
            # 简单的文件检查
            for file in "$ARTIFACT_DIR"/*.tar.gz; do
                if [[ -f "$file" ]]; then
                    existing_components=$((existing_components + 1))
                fi
            done
        fi
        
        # 如果所有文件都存在，则跳过打包
        if [[ $missing_files -eq 0 && $existing_components -gt 0 ]]; then
            log_success "版本 $VERSION 已完整打包，跳过重复打包"
            echo
            echo "现有文件:"
            ls -la "$ARTIFACT_DIR"
            echo
            echo "如需强制重新打包，请删除目录: rm -rf $ARTIFACT_DIR"
            echo "或使用: ./package.sh --force"
            exit 0
        else
            log_warning "版本 $VERSION 存在但不完整，将重新打包"
            log_info "  现有组件: $existing_components"
            log_info "  缺少文件: $missing_files"
        fi
    else
        log_warning "版本目录存在但缺少 version.json，将重新打包"
    fi
fi

# 创建 artifact 目录
mkdir -p "$ARTIFACT_DIR"
log_info "创建输出目录: $ARTIFACT_DIR"

# 创建临时文件存储数据
TEMP_DIR=$(mktemp -d)
COMPONENTS_FILE="$TEMP_DIR/components.txt"
VERSIONS_FILE="$TEMP_DIR/versions.txt"
DEPENDENCIES_FILE="$TEMP_DIR/dependencies.txt"
INSTALL_ORDER_FILE="$TEMP_DIR/install_order.txt"
CHECKSUMS_FILE="$TEMP_DIR/checksums.txt"
ARTIFACT_LIST_FILE="$TEMP_DIR/artifact_list.txt"

# 解析 checklist 文件
log_info "解析组件清单..."
line_num=0
component_count=0

while IFS= read -r line; do
    [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
    
    line_num=$((line_num + 1))
    
    # 解析行: 组件名 目录路径 版本 [依赖组件] [安装顺序]
    read -r component component_path version dep_component order <<< "$line"
    
    if [[ -z "$component" || -z "$component_path" || -z "$version" ]]; then
        log_warning "跳过无效行 $line_num: $line"
        continue
    fi
    
    # 存储组件信息
    echo "$component" >> "$COMPONENTS_FILE"
    echo "$component:$version" >> "$VERSIONS_FILE"
    echo "$component:$component_path" >> "$TEMP_DIR/component_paths.txt"
    
    if [[ -n "$dep_component" && "$dep_component" != "$component" ]]; then
        echo "$component:$dep_component" >> "$DEPENDENCIES_FILE"
    fi
    
    if [[ -n "$order" && "$order" =~ ^[0-9]+$ ]]; then
        echo "$order:$component" >> "$INSTALL_ORDER_FILE"
    else
        # 如果没有指定顺序，按解析顺序分配
        echo "$line_num:$component" >> "$INSTALL_ORDER_FILE"
    fi
    
    component_count=$((component_count + 1))
    log_info "  - $component v$version"
done < config/checklist

if [[ $component_count -eq 0 ]]; then
    log_error "没有找到有效的组件"
    rm -rf "$TEMP_DIR"
    exit 1
fi

log_success "找到 $component_count 个组件"

# 检查组件目录是否存在
log_info "检查组件目录..."
missing_components=()

while IFS= read -r component; do
    # 获取组件路径
    component_path=$(grep "^$component:" "$TEMP_DIR/component_paths.txt" | cut -d':' -f2-)
    if [[ -z "$component_path" ]]; then
        log_error "未找到组件 $component 的路径配置"
        log_info "请检查 component_paths.txt 文件或添加路径配置"
        exit 1
    fi
    
    if [[ ! -d "$component_path" ]]; then
        missing_components+=("$component:$component_path")
    fi
done < "$COMPONENTS_FILE"

if [[ ${#missing_components[@]} -gt 0 ]]; then
    log_error "以下组件目录不存在:"
    for component_path in "${missing_components[@]}"; do
        echo "  - $component_path"
    done
    rm -rf "$TEMP_DIR"
    exit 1
fi

# 打包各个组件
log_info "开始打包组件..."

while IFS= read -r component; do
    # 获取组件版本和路径
    version=$(grep "^$component:" "$VERSIONS_FILE" | cut -d':' -f2)
    component_path=$(grep "^$component:" "$TEMP_DIR/component_paths.txt" | cut -d':' -f2-)
    if [[ -z "$component_path" ]]; then
        log_error "未找到组件 $component 的路径配置"
        log_info "请检查 component_paths.txt 文件或添加路径配置"
        exit 1
    fi
    
    log_info "打包 $component v$version..."
    log_info "  组件路径: $component_path"
    
    # 进入组件目录
    cd "$component_path"
    
    # 检查组件是否有 package.sh
    if [[ ! -f "package.sh" ]]; then
        log_error "$component 缺少 package.sh 文件"
        cd "$CURRENT_DIR"
        rm -rf "$TEMP_DIR"
        exit 1
    fi
    
    # 执行组件的打包脚本
    if ./package.sh; then
        # 查找生成的 tar 包
        tar_file=$(find . -name "*.tar.gz" -type f | head -1)
        if [[ -n "$tar_file" ]]; then
            # 移动到 artifact 目录
            mv "$tar_file" "$CURRENT_DIR/$ARTIFACT_DIR/"
            tar_filename=$(basename "$tar_file")
            
            # 计算校验和
            checksum=$(sha256sum "$CURRENT_DIR/$ARTIFACT_DIR/$tar_filename" | cut -d' ' -f1)
            echo "$component:sha256:$checksum" >> "$CHECKSUMS_FILE"
            echo "$component:$version" >> "$ARTIFACT_LIST_FILE"
            
            # 将完整的文件名存储到安装顺序文件中
            echo "$tar_filename" >> "$TEMP_DIR/install_order_files.txt"
            
            log_success "  $component 打包完成: $tar_filename"
        else
            log_error "$component 打包失败，未找到生成的 tar 包"
            cd "$CURRENT_DIR"
            rm -rf "$TEMP_DIR"
            exit 1
        fi
    else
        log_error "$component 打包失败"
        cd "$CURRENT_DIR"
        rm -rf "$TEMP_DIR"
        exit 1
    fi
    
    # 返回主目录
    cd "$CURRENT_DIR"
done < "$COMPONENTS_FILE"

# 生成 version.json
log_info "生成版本信息文件..."
version_json="$ARTIFACT_DIR/version.json"

# 构建依赖关系 JSON
deps_json=""
if [[ -f "$DEPENDENCIES_FILE" ]]; then
    first=true
    while IFS= read -r line; do
        component=$(echo "$line" | cut -d':' -f1)
        dep=$(echo "$line" | cut -d':' -f2)
        if [[ "$first" == "true" ]]; then
            deps_json="\"$component\":[\"$dep\"]"
            first=false
        else
            deps_json="$deps_json,\"$component\":[\"$dep\"]"
        fi
    done < "$DEPENDENCIES_FILE"
fi

# 构建安装顺序数组
order_array=""
if [[ -f "$TEMP_DIR/install_order_files.txt" ]]; then
    first=true
    while IFS= read -r filename; do
        if [[ "$first" == "true" ]]; then
            order_array="\"$filename\""
            first=false
        else
            order_array="$order_array,\"$filename\""
        fi
    done < "$TEMP_DIR/install_order_files.txt"
fi

# 构建 artifact_list JSON
artifact_json=""
if [[ -f "$ARTIFACT_LIST_FILE" ]]; then
    first=true
    while IFS= read -r line; do
        component=$(echo "$line" | cut -d':' -f1)
        version=$(echo "$line" | cut -d':' -f2)
        if [[ "$first" == "true" ]]; then
            artifact_json="\"$component\":\"$version\""
            first=false
        else
            artifact_json="$artifact_json,\"$component\":\"$version\""
        fi
    done < "$ARTIFACT_LIST_FILE"
fi

# 构建 checksums JSON
checksums_json=""
if [[ -f "$CHECKSUMS_FILE" ]]; then
    first=true
    while IFS= read -r line; do
        component=$(echo "$line" | cut -d':' -f1)
        checksum=$(echo "$line" | cut -d':' -f2-)
        if [[ "$first" == "true" ]]; then
            checksums_json="\"$component\":\"$checksum\""
            first=false
        else
            checksums_json="$checksums_json,\"$component\":\"$checksum\""
        fi
    done < "$CHECKSUMS_FILE"
fi

# 生成完整的 version.json
cat > "$version_json" << EOF
{
  "version": "$VERSION",
  "build_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "artifact_list": {
    $artifact_json
  },
  "checksums": {
    $checksums_json
  },
  "dependencies": {
    $deps_json
  },
  "install_order": [
    $order_array
  ]
}
EOF

log_success "版本信息文件生成完成: $version_json"

# 复制`安装`脚本到 artifact 目录
log_info "复制安装脚本..."
if [[ -f "scripts/install_artifact.sh" ]]; then
    cp "scripts/install_artifact.sh" "$ARTIFACT_DIR/install.sh"
    chmod +x "$ARTIFACT_DIR/install.sh"
    log_success "安装脚本复制完成: $ARTIFACT_DIR/install.sh"
else
    log_warning "scripts/install_artifact.sh 文件不存在"
fi

# 复制`卸载`脚本到 artifact 目录
log_info "复制卸载脚本..."
if [[ -f "scripts/uninstall_artifact.sh" ]]; then
    cp "scripts/uninstall_artifact.sh" "$ARTIFACT_DIR/uninstall.sh"
    chmod +x "$ARTIFACT_DIR/uninstall.sh"
    log_success "卸载脚本复制完成: $ARTIFACT_DIR/uninstall.sh"
else
    log_warning "scripts/uninstall_artifact.sh 文件不存在"
fi

# 复制`健康检查`脚本到 artifact 目录
log_info "复制健康检查脚本..."
if [[ -f "scripts/check_health.sh" ]]; then
    cp "scripts/check_health.sh" "$ARTIFACT_DIR/check_health.sh"
    chmod +x "$ARTIFACT_DIR/check_health.sh"
    log_success "健康检查脚本复制完成: $ARTIFACT_DIR/check_health.sh"
else
    log_warning "scripts/check_health.sh 文件不存在"
fi

# 复制`DNS 同步`脚本到 artifact 目录
log_info "复制 DNS 同步脚本..."
if [[ -f "scripts/sync_dns.sh" ]]; then
    cp "scripts/sync_dns.sh" "$ARTIFACT_DIR/sync_dns.sh"
    chmod +x "$ARTIFACT_DIR/sync_dns.sh"
    log_success "DNS 同步脚本复制完成: $ARTIFACT_DIR/sync_dns.sh"
else
    log_warning "scripts/sync_dns.sh 文件不存在"
fi

# 复制`版本校验`脚本到 artifact 目录
log_info "复制版本校验脚本..."
if [[ -f "scripts/check_version.sh" ]]; then
    cp "scripts/check_version.sh" "$ARTIFACT_DIR/check_version.sh"
    chmod +x "$ARTIFACT_DIR/check_version.sh"
    log_success "版本校验脚本复制完成: $ARTIFACT_DIR/check_version.sh"
else
    log_warning "scripts/check_version.sh 文件不存在"
fi

# 复制`自动重启`脚本到 artifact 目录
log_info "复制自动重启脚本..."
if [[ -f "scripts/restart_unhealthy.sh" ]]; then
    cp "scripts/restart_unhealthy.sh" "$ARTIFACT_DIR/restart_unhealthy.sh"
    chmod +x "$ARTIFACT_DIR/restart_unhealthy.sh"
    log_success "自动重启脚本复制完成: $ARTIFACT_DIR/restart_unhealthy.sh"
else
    log_warning "scripts/restart_unhealthy.sh 文件不存在"
fi

# 复制配置文件到 artifact 目录
log_info "复制配置文件..."
if [[ -f "config/config.env" ]]; then
    cp "config/config.env" "$ARTIFACT_DIR/"
    log_success "配置文件复制完成: $ARTIFACT_DIR/config.env"
else
    log_warning "config 目录不存在，跳过配置文件复制"
fi

# DNS 配置文件不需要复制到版本目录，直接从 FTP 服务器根目录获取

# 复制 deps 目录到 artifact 目录
log_info "复制系统依赖包..."
if [[ -d "deps" ]]; then
    cp -r "deps" "$ARTIFACT_DIR/"
    log_success "系统依赖包复制完成: $ARTIFACT_DIR/deps"
    
    # 显示deps目录内容
    log_info "  依赖包列表:"
    find "$ARTIFACT_DIR/deps" -name "*.tar.gz" -exec basename {} \; | while read dep_file; do
        log_info "    - $dep_file"
    done
else
    log_warning "deps 目录不存在，跳过依赖包复制"
fi

# 显示打包结果
log_success "打包完成！"
echo
echo "版本: $VERSION"
echo "输出目录: $ARTIFACT_DIR"
echo "包含组件:"
if [[ -f "$ARTIFACT_LIST_FILE" ]]; then
    while IFS= read -r line; do
        component=$(echo "$line" | cut -d':' -f1)
        version=$(echo "$line" | cut -d':' -f2)
        echo "  - $component v$version"
    done < "$ARTIFACT_LIST_FILE"
fi
echo
echo "文件列表:"
ls -la "$ARTIFACT_DIR"
echo

# 清理临时文件
rm -rf "$TEMP_DIR"
