#!/bin/bash

# =============================================================================
# Neo4j同步程序运行脚本
# 适用于Linux生产环境
# =============================================================================

# 脚本配置
SCRIPT_NAME="run_parse_neo4j.sh"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$SCRIPT_DIR"
PYTHON_SCRIPT="$PROJECT_ROOT/app/core/data_parse/parse_neo4j_process.py"
LOG_DIR="$PROJECT_ROOT/logs"
LOG_FILE="$LOG_DIR/parse_neo4j_$(date +%Y%m%d_%H%M%S).log"
PID_FILE="$PROJECT_ROOT/parse_neo4j.pid"
LOCK_FILE="$PROJECT_ROOT/parse_neo4j.lock"

# 环境变量
export PYTHONPATH="$PROJECT_ROOT:$PYTHONPATH"
export PYTHONUNBUFFERED=1

# 颜色定义
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 "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] [INFO]${NC} $1" | tee -a "$LOG_FILE"
}

log_warn() {
    echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] [WARN]${NC} $1" | tee -a "$LOG_FILE"
}

log_error() {
    echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR]${NC} $1" | tee -a "$LOG_FILE"
}

log_debug() {
    echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] [DEBUG]${NC} $1" | tee -a "$LOG_FILE"
}

# 清理函数
cleanup() {
    log_info "执行清理操作..."
    
    # 删除PID文件
    if [ -f "$PID_FILE" ]; then
        rm -f "$PID_FILE"
        log_info "已删除PID文件: $PID_FILE"
    fi
    
    # 删除锁文件
    if [ -f "$LOCK_FILE" ]; then
        rm -f "$LOCK_FILE"
        log_info "已删除锁文件: $LOCK_FILE"
    fi
    
    log_info "清理操作完成"
}

# 信号处理
trap cleanup EXIT
trap 'log_error "收到中断信号，正在退出..."; exit 1' INT TERM

# 检查依赖
check_dependencies() {
    log_info "检查系统依赖..."
    
    # 检查Python
    if ! command -v python3 &> /dev/null; then
        log_error "Python3 未安装或不在PATH中"
        return 1
    fi
    
    PYTHON_VERSION=$(python3 --version 2>&1)
    log_info "Python版本: $PYTHON_VERSION"
    
    # 检查pip
    if ! command -v pip3 &> /dev/null; then
        log_error "pip3 未安装或不在PATH中"
        return 1
    fi
    
    # 检查虚拟环境（如果存在）
    if [ -d "$PROJECT_ROOT/venv" ]; then
        log_info "检测到虚拟环境: $PROJECT_ROOT/venv"
        source "$PROJECT_ROOT/venv/bin/activate"
        log_info "已激活虚拟环境"
    fi
    
    return 0
}

# 检查Python包依赖
check_python_packages() {
    log_info "检查Python包依赖..."
    
    local required_packages=(
        "psycopg2-binary"
        "neo4j"
        "openai"
        "boto3"
        "Pillow"
        "pytesseract"
        "requests"
    )
    
    for package in "${required_packages[@]}"; do
        if ! python3 -c "import ${package//-/_}" 2>/dev/null; then
            log_warn "Python包未安装: $package"
            if [ "$1" = "--install" ]; then
                log_info "尝试安装包: $package"
                pip3 install "$package" || log_error "安装包失败: $package"
            fi
        else
            log_debug "Python包已安装: $package"
        fi
    done
}

# 创建日志目录
create_log_dir() {
    if [ ! -d "$LOG_DIR" ]; then
        mkdir -p "$LOG_DIR"
        log_info "创建日志目录: $LOG_DIR"
    fi
}

# 检查是否已在运行
check_running() {
    if [ -f "$PID_FILE" ]; then
        local pid=$(cat "$PID_FILE")
        if ps -p "$pid" > /dev/null 2>&1; then
            log_error "程序已在运行，PID: $pid"
            return 1
        else
            log_warn "发现过期的PID文件，正在清理..."
            rm -f "$PID_FILE"
        fi
    fi
    
    if [ -f "$LOCK_FILE" ]; then
        log_error "发现锁文件，可能程序正在运行或上次异常退出"
        return 1
    fi
    
    return 0
}

# 创建锁文件
create_lock() {
    echo "$$" > "$LOCK_FILE"
    echo "$$" > "$PID_FILE"
    log_info "创建锁文件和PID文件"
}

# 检查数据库连接
check_database_connection() {
    log_info "检查数据库连接..."
    
    # 这里可以添加数据库连接检查逻辑
    # 例如：检查PostgreSQL和Neo4j是否可访问
    
    log_info "数据库连接检查完成"
}

# 运行主程序
run_main_program() {
    log_info "开始运行Neo4j同步程序..."
    log_info "工作目录: $PROJECT_ROOT"
    log_info "Python脚本: $PYTHON_SCRIPT"
    log_info "日志文件: $LOG_FILE"
    
    # 运行Python脚本
    cd "$PROJECT_ROOT"
    python3 "$PYTHON_SCRIPT" 2>&1 | tee -a "$LOG_FILE"
    
    local exit_code=$?
    
    if [ $exit_code -eq 0 ]; then
        log_info "程序执行成功"
    else
        log_error "程序执行失败，退出码: $exit_code"
    fi
    
    return $exit_code
}

# 显示帮助信息
show_help() {
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  -h, --help          显示此帮助信息"
    echo "  -v, --version       显示版本信息"
    echo "  -i, --install       自动安装缺失的Python包"
    echo "  -c, --check         只检查依赖，不运行程序"
    echo "  -f, --force         强制运行（忽略锁文件检查）"
    echo "  -l, --log-dir DIR   指定日志目录"
    echo ""
    echo "示例:"
    echo "  $0                   正常运行程序"
    echo "  $0 --install         安装依赖后运行程序"
    echo "  $0 --check           只检查依赖"
    echo "  $0 --force           强制运行程序"
}

# 显示版本信息
show_version() {
    echo "Neo4j同步程序运行脚本 v1.0.0"
    echo "适用于Linux生产环境"
}

# 主函数
main() {
    local force_run=false
    local check_only=false
    local install_packages=false
    
    # 解析命令行参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -v|--version)
                show_version
                exit 0
                ;;
            -i|--install)
                install_packages=true
                shift
                ;;
            -c|--check)
                check_only=true
                shift
                ;;
            -f|--force)
                force_run=true
                shift
                ;;
            -l|--log-dir)
                LOG_DIR="$2"
                shift 2
                ;;
            *)
                log_error "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
    
    # 创建日志目录
    create_log_dir
    
    # 记录脚本启动
    log_info "=========================================="
    log_info "Neo4j同步程序运行脚本启动"
    log_info "脚本路径: $0"
    log_info "启动时间: $(date)"
    log_info "=========================================="
    
    # 检查依赖
    if ! check_dependencies; then
        log_error "依赖检查失败，程序退出"
        exit 1
    fi
    
    # 检查Python包
    check_python_packages $([ "$install_packages" = true ] && echo "--install")
    
    # 如果只是检查依赖，则退出
    if [ "$check_only" = true ]; then
        log_info "依赖检查完成，程序退出"
        exit 0
    fi
    
    # 检查是否已在运行
    if [ "$force_run" = false ] && ! check_running; then
        log_error "程序已在运行或存在锁文件，程序退出"
        exit 1
    fi
    
    # 创建锁文件
    create_lock
    
    # 检查数据库连接
    check_database_connection
    
    # 运行主程序
    if run_main_program; then
        log_info "程序执行完成"
        exit 0
    else
        log_error "程序执行失败"
        exit 1
    fi
}

# 脚本入口点
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi 