#!/bin/bash
# filepath: ocr_platform/ocr_tools/daemons/ppstructure_v3_daemon.sh
# 对应客户端工具: ocr_tools/ppstructure_tool/api_client.py

# PaddleX PP-StructureV3 服务守护进程脚本

LOGDIR="/home/ubuntu/zhch/logs"
mkdir -p $LOGDIR
PIDFILE="$LOGDIR/ppstructurev3.pid"
LOGFILE="$LOGDIR/ppstructurev3.log"

# 配置参数
CONDA_ENV="paddle"  # 根据您的study-notes.md中的环境名
PORT="8111"
CUDA_VISIBLE_DEVICES=7

# 脚本和配置路径
# 方式1：使用迁移后的路径（推荐）
PADDLE_COMMON_DIR="/path/to/ocr_platform/ocr_tools/paddle_common"
# 方式2：使用原始路径（如果尚未迁移）
# PADDLE_COMMON_DIR="/home/ubuntu/zhch/PaddleX/zhch"

# Pipeline 配置文件路径
# 可以使用 ocr_tools/paddle_common/config/ 中的配置文件（推荐）
PIPELINE_CONFIG="$PADDLE_COMMON_DIR/config/PP-StructureV3.yaml"
# 或者使用原始配置路径（如果尚未迁移）:
# PIPELINE_CONFIG="/home/ubuntu/zhch/PaddleX/zhch/my_config/PP-StructureV3.yaml"
# PIPELINE_CONFIG="$PADDLE_COMMON_DIR/config/PP-StructureV3-RT-DETR-H_layout_17cls.yaml"

# start_paddlex_with_adapter.py 脚本路径
START_SCRIPT="$PADDLE_COMMON_DIR/start_paddlex_with_adapter.py"

# 正确初始化和激活conda环境
# 方法1：使用conda.sh脚本初始化
if [ -f "/home/ubuntu/anaconda3/etc/profile.d/conda.sh" ]; then
    source /home/ubuntu/anaconda3/etc/profile.d/conda.sh
    conda activate $CONDA_ENV
elif [ -f "/opt/conda/etc/profile.d/conda.sh" ]; then
    source /opt/conda/etc/profile.d/conda.sh
    conda activate $CONDA_ENV
else
    # 方法2：直接使用conda可执行文件路径
    echo "Warning: Using direct conda path activation"
    export PATH="/home/ubuntu/anaconda3/envs/$CONDA_ENV/bin:$PATH"
fi

# 设置模型下载源（可选）
export PADDLE_PDX_MODEL_SOURCE="bos"
export PADDLEX_ENABLE_ADAPTER="true"
export PYTHONWARNINGS="ignore::UserWarning"

start() {
    if [ -f $PIDFILE ] && kill -0 $(cat $PIDFILE) 2>/dev/null; then
        echo "PaddleX PP-StructureV3 is already running"
        return 1
    fi
    
    echo "Starting PaddleX PP-StructureV3 daemon..."
    echo "Port: $PORT"
    echo "CUDA Devices: $CUDA_VISIBLE_DEVICES"
    echo "Pipeline config: $PIPELINE_CONFIG"
    
    # 检查配置文件是否存在
    if [ ! -f "$PIPELINE_CONFIG" ]; then
        echo "❌ Pipeline config file not found: $PIPELINE_CONFIG"
        return 1
    fi
    
    # 检查conda环境
    if ! command -v python >/dev/null 2>&1; then
        echo "❌ Python not found. Check conda environment activation."
        return 1
    fi
    
    # 检查paddlex命令
    if ! command -v paddlex >/dev/null 2>&1; then
        echo "❌ PaddleX not found. Check installation and environment."
        return 1
    fi
    
    echo "🔧 Using Python: $(which python)"
    echo "🔧 Using PaddleX: $(which paddlex)"
    echo "  CUDA Devices: $CUDA_VISIBLE_DEVICES"
    
    # 检查 start_paddlex_with_adapter.py 是否存在
    if [ ! -f "$START_SCRIPT" ]; then
        echo "❌ start_paddlex_with_adapter.py not found: $START_SCRIPT"
        echo "Please update PADDLE_COMMON_DIR in the script to point to the correct location"
        return 1
    fi
    
    # 启动PaddleX服务
    # 切换到脚本所在目录，确保相对路径正确
    cd "$(dirname "$START_SCRIPT")" || exit 1
    CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES nohup python3 "$START_SCRIPT" --serve \
        --port $PORT \
        --device "gpu" \
        --pipeline "$PIPELINE_CONFIG" \
        > $LOGFILE 2>&1 &
    
    echo $! > $PIDFILE
    echo "✅ PaddleX PP-StructureV3 started with PID: $(cat $PIDFILE)"
    echo "📋 Log file: $LOGFILE"
    echo "🌐 Service URL: http://localhost:$PORT"
    echo "🌐 API Endpoint: http://localhost:$PORT/layout-parsing"
    echo "📖 API Documentation: http://localhost:$PORT/docs"
}

stop() {
    if [ ! -f $PIDFILE ]; then
        echo "PaddleX PP-StructureV3 is not running"
        return 1
    fi
    
    PID=$(cat $PIDFILE)
    echo "Stopping PaddleX PP-StructureV3 (PID: $PID)..."
    
    # 优雅停止
    kill $PID
    
    # 等待进程结束
    for i in {1..10}; do
        if ! kill -0 $PID 2>/dev/null; then
            break
        fi
        echo "Waiting for process to stop... ($i/10)"
        sleep 1
    done
    
    # 如果进程仍在运行，强制结束
    if kill -0 $PID 2>/dev/null; then
        echo "Force killing process..."
        kill -9 $PID
    fi
    
    rm -f $PIDFILE
    echo "✅ PaddleX PP-StructureV3 stopped"
}

status() {
    if [ -f $PIDFILE ] && kill -0 $(cat $PIDFILE) 2>/dev/null; then
        PID=$(cat $PIDFILE)
        echo "✅ PaddleX PP-StructureV3 is running (PID: $PID)"
        echo "🌐 Service URL: http://localhost:$PORT"
        echo "🌐 API Endpoint: http://localhost:$PORT/layout-parsing"
        echo "📋 Log file: $LOGFILE"
        
        # 检查端口是否被监听
        if command -v ss >/dev/null 2>&1; then
            if ss -tuln | grep -q ":$PORT "; then
                echo "🔗 Port $PORT is being listened"
            else
                echo "⚠️  Port $PORT is not being listened (service may be starting up)"
            fi
        elif command -v netstat >/dev/null 2>&1; then
            if netstat -tuln | grep -q ":$PORT "; then
                echo "🔗 Port $PORT is being listened"
            else
                echo "⚠️  Port $PORT is not being listened (service may be starting up)"
            fi
        fi
        
        # 检查API响应
        if command -v curl >/dev/null 2>&1; then
            if curl -s --connect-timeout 2 http://127.0.0.1:$PORT/layout-parsing > /dev/null 2>&1; then
                echo "🎯 API 响应正常"
            else
                echo "⚠️  API 无响应 (service may be starting up)"
            fi
        fi
        
        # 显示最新日志
        if [ -f $LOGFILE ]; then
            echo "📄 Latest logs (last 5 lines):"
            tail -5 $LOGFILE | sed 's/^/  /'
        fi
    else
        echo "❌ PaddleX PP-StructureV3 is not running"
        if [ -f $PIDFILE ]; then
            echo "Removing stale PID file..."
            rm -f $PIDFILE
        fi
    fi
}

logs() {
    if [ -f $LOGFILE ]; then
        echo "📄 PaddleX PP-StructureV3 logs:"
        echo "=================="
        tail -f $LOGFILE
    else
        echo "❌ Log file not found: $LOGFILE"
    fi
}

config() {
    echo "📋 Current configuration:"
    echo "  Conda Environment: $CONDA_ENV"
    echo "  Port: $PORT"
    echo "  CUDA Visible Devices: $CUDA_VISIBLE_DEVICES"
    echo "  Pipeline Config: $PIPELINE_CONFIG"
    echo "  Paddle Common Directory: $PADDLE_COMMON_DIR"
    echo "  Start Script: $START_SCRIPT"
    echo "  Model Source: ${PADDLE_PDX_MODEL_SOURCE:-default}"
    echo "  PID File: $PIDFILE"
    echo "  Log File: $LOGFILE"
    
    if [ -f "$PIPELINE_CONFIG" ]; then
        echo "✅ Pipeline config file exists"
    else
        echo "❌ Pipeline config file not found: $PIPELINE_CONFIG"
    fi
    
    # 检查 start_paddlex_with_adapter.py 是否存在
    if [ -f "$START_SCRIPT" ]; then
        echo "✅ start_paddlex_with_adapter.py exists"
    else
        echo "❌ start_paddlex_with_adapter.py not found: $START_SCRIPT"
        echo "   Please update PADDLE_COMMON_DIR in the script"
    fi
    
    # 显示环境信息
    echo ""
    echo "🔧 Environment:"
    echo "  Python: $(which python 2>/dev/null || echo 'Not found')"
    echo "  PaddleX: $(which paddlex 2>/dev/null || echo 'Not found')"
    echo "  Conda: $(which conda 2>/dev/null || echo 'Not found')"
}

# 显示使用帮助
usage() {
    echo "PaddleX PP-StructureV3 Service Daemon"
    echo "======================================"
    echo "Usage: $0 {start|stop|restart|status|logs|config}"
    echo ""
    echo "Commands:"
    echo "  start   - Start the PaddleX PP-StructureV3 service"
    echo "  stop    - Stop the PaddleX PP-StructureV3 service"
    echo "  restart - Restart the PaddleX PP-StructureV3 service"
    echo "  status  - Show service status"
    echo "  logs    - Show service logs (follow mode)"
    echo "  config  - Show current configuration"
    echo ""
    echo "Configuration (edit script to modify):"
    echo "  Port: $PORT"
    echo "  CUDA Devices: $CUDA_VISIBLE_DEVICES"
    echo "  Pipeline: $PIPELINE_CONFIG"
    echo ""
    echo "Examples:"
    echo "  ./ppstructure_v3_daemon.sh start"
    echo "  ./ppstructure_v3_daemon.sh status"
    echo "  ./ppstructure_v3_daemon.sh logs"
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 3
        start
        ;;
    status)
        status
        ;;
    logs)
        logs
        ;;
    config)
        config
        ;;
    *)
        usage
        exit 1
        ;;
esac

