#!/bin/bash

# =========================================
# 定时任务调度服务 - 启动脚本
# =========================================

set -e

APP_NAME="scheduled-task-service"
APP_HOME="/opt/erp/${APP_NAME}"
LOG_HOME="/var/log/erp/${APP_NAME}"
CONFIG_HOME="/etc/erp/${APP_NAME}"

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

log() {
    echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}

warn() {
    echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}

error() {
    echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}

# 检查Java
check_java() {
    if ! command -v java &> /dev/null; then
        error "Java not found. Please install JDK 17+"
        exit 1
    fi
    
    JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d'.' -f1)
    if [ "$JAVA_VERSION" -lt 17 ]; then
        error "Java 17+ required, current version: $JAVA_VERSION"
        exit 1
    fi
    
    log "Java version check passed"
}

# 创建目录
create_dirs() {
    log "Creating directories..."
    mkdir -p ${APP_HOME}
    mkdir -p ${LOG_HOME}
    mkdir -p ${CONFIG_HOME}
}

# 备份配置
backup_config() {
    if [ -f "${CONFIG_HOME}/application.yml" ]; then
        BACKUP_FILE="${CONFIG_HOME}/application.yml.bak.$(date +%Y%m%d%H%M%S)"
        warn "Backing up config to: ${BACKUP_FILE}"
        cp ${CONFIG_HOME}/application.yml ${BACKUP_FILE}
    fi
}

# 启动应用
start_app() {
    log "Starting ${APP_NAME}..."
    
    cd ${APP_HOME}
    
    JAVA_OPTS="-Xms512m -Xmx1024m"
    JAVA_OPTS="${JAVA_OPTS} -XX:+UseG1GC"
    JAVA_OPTS="${JAVA_OPTS} -XX:+HeapDumpOnOutOfMemoryError"
    JAVA_OPTS="${JAVA_OPTS} -XX:HeapDumpPath=${LOG_HOME}/heapdump.hprof"
    JAVA_OPTS="${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom"
    JAVA_OPTS="${JAVA_OPTS} -Dspring.config.additional-location=${CONFIG_HOME}/"
    JAVA_OPTS="${JAVA_OPTS} -Dlogging.file.path=${LOG_HOME}"
    
    nohup java ${JAVA_OPTS} -jar ${APP_HOME}/${APP_NAME}.jar \
        --spring.config.additional-location=${CONFIG_HOME}/ \
        >> ${LOG_HOME}/stdout.log 2>&1 &
    
    APP_PID=$!
    echo ${APP_PID} > ${APP_HOME}/app.pid
    
    log "${APP_NAME} started with PID: ${APP_PID}"
    
    # 等待应用启动
    wait_for_app
}

# 等待应用启动完成
wait_for_app() {
    log "Waiting for application to start..."
    
    MAX_WAIT=120
    COUNTER=0
    
    while [ $COUNTER -lt $MAX_WAIT ]; do
        if curl -sf http://localhost:8088/actuator/health > /dev/null 2>&1; then
            log "${APP_NAME} is ready!"
            return 0
        fi
        
        if ! ps -p $APP_PID > /dev/null 2>&1; then
            error "Application process died!"
            tail -100 ${LOG_HOME}/stdout.log
            exit 1
        fi
        
        sleep 2
        COUNTER=$((COUNTER + 2))
        echo -n "."
    done
    
    error "Application failed to start within ${MAX_WAIT} seconds"
    tail -100 ${LOG_HOME}/stdout.log
    exit 1
}

# 停止应用
stop_app() {
    log "Stopping ${APP_NAME}..."
    
    if [ -f ${APP_HOME}/app.pid ]; then
        PID=$(cat ${APP_HOME}/app.pid)
        
        if ps -p $PID > /dev/null 2>&1; then
            kill -15 $PID
            
            # 等待最多30秒
            for i in {1..30}; do
                if ! ps -p $PID > /dev/null 2>&1; then
                    log "${APP_NAME} stopped"
                    rm -f ${APP_HOME}/app.pid
                    return 0
                fi
                sleep 1
            done
            
            # 强制kill
            warn "Force killing ${APP_NAME}..."
            kill -9 $PID 2>/dev/null || true
            rm -f ${APP_HOME}/app.pid
        else
            warn "Process $PID not found"
            rm -f ${APP_HOME}/app.pid
        fi
    else
        warn "PID file not found"
        
        # 尝试查找进程
        PID=$(pgrep -f ${APP_NAME})
        if [ -n "$PID" ]; then
            warn "Found process: $PID, killing..."
            kill -15 $PID 2>/dev/null || true
            sleep 5
            pkill -9 -f ${APP_NAME} 2>/dev/null || true
        fi
    fi
}

# 查看状态
status() {
    if [ -f ${APP_HOME}/app.pid ]; then
        PID=$(cat ${APP_HOME}/app.pid)
        if ps -p $PID > /dev/null 2>&1; then
            log "${APP_NAME} is running (PID: $PID)"
            
            if curl -sf http://localhost:8088/actuator/health > /dev/null 2>&1; then
                log "Health check: OK"
            else
                warn "Health check: FAILED"
            fi
        else
            warn "${APP_NAME} is not running (stale PID file)"
        fi
    else
        PID=$(pgrep -f ${APP_NAME})
        if [ -n "$PID" ]; then
            log "${APP_NAME} is running (PID: $PID)"
        else
            warn "${APP_NAME} is not running"
        fi
    fi
}

# 查看日志
logs() {
    tail -f ${LOG_HOME}/stdout.log
}

# 构建项目
build() {
    log "Building ${APP_NAME}..."
    cd $(dirname $(dirname $(readlink -f $0)))
    
    if [ -f "pom.xml" ]; then
        ./mvnw clean package -DskipTests
    else
        error "pom.xml not found"
        exit 1
    fi
    
    log "Build completed"
}

# 打包Docker镜像
docker_build() {
    log "Building Docker image..."
    cd ${APP_HOME}/..
    
    docker build -t ${APP_NAME}:1.0.0 -f deploy/docker/Dockerfile .
    
    log "Docker image built: ${APP_NAME}:1.0.0"
}

# 主菜单
usage() {
    echo ""
    echo "========================================="
    echo "  定时任务调度服务管理脚本"
    echo "========================================="
    echo ""
    echo "Usage: $0 {start|stop|restart|status|logs|build|docker_build}"
    echo ""
    echo "Commands:"
    echo "  start        - Start the application"
    echo "  stop         - Stop the application"
    echo "  restart      - Restart the application"
    echo "  status       - Check application status"
    echo "  logs         - View application logs"
    echo "  build        - Build the application"
    echo "  docker_build - Build Docker image"
    echo ""
}

# 主入口
case "$1" in
    start)
        check_java
        create_dirs
        backup_config
        start_app
        ;;
    stop)
        stop_app
        ;;
    restart)
        stop_app
        sleep 5
        start_app
        ;;
    status)
        status
        ;;
    logs)
        logs
        ;;
    build)
        build
        ;;
    docker_build)
        docker_build
        ;;
    *)
        usage
        exit 1
        ;;
esac

exit 0
