/*
 * 文 件 名:  ChargingPileExecutorConfig
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  充电桩线程池配置
 * 修 改 人:  lvwenbin
 * 修改时间:  2025/12/23
 */
package com.ruoyi.ems.charging.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 充电桩线程池配置
 * 读取yml中的executor配置并创建线程池Bean
 *
 * @author lvwenbin
 * @version [版本号, 2025/12/23]
 */
@Configuration
@EnableAsync
@ConfigurationProperties(prefix = "charging-pile.executor")
public class ChargingPileExecutorConfig {

    private static final Logger log = LoggerFactory.getLogger(ChargingPileExecutorConfig.class);

    /**
     * Boss组线程池配置
     */
    private ExecutorProperties bossGroup = new ExecutorProperties();

    /**
     * Worker组线程池配置
     */
    private ExecutorProperties workerGroup = new ExecutorProperties();

    /**
     * 消息处理线程池配置
     */
    private ExecutorProperties msgExec = new ExecutorProperties();

    /**
     * 消息处理线程池Bean
     * 对应 @Async("msgExecExecutor") 注解
     */
    @Bean("msgExecExecutor")
    public Executor msgExecExecutor() {
        log.info("初始化充电桩消息处理线程池 msgExecExecutor");
        log.info("配置: corePoolSize={}, maxPoolSize={}, queueCapacity={}, namePrefix={}",
                msgExec.getCorePoolSize(), msgExec.getMaxPoolSize(),
                msgExec.getQueueCapacity(), msgExec.getNamePrefix());

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        // 核心线程数
        executor.setCorePoolSize(msgExec.getCorePoolSize());

        // 最大线程数
        executor.setMaxPoolSize(msgExec.getMaxPoolSize());

        // 队列容量
        executor.setQueueCapacity(msgExec.getQueueCapacity());

        // 线程名前缀
        executor.setThreadNamePrefix(msgExec.getNamePrefix());

        // 线程空闲时间(秒)
        executor.setKeepAliveSeconds(60);

        // 拒绝策略：由调用线程执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        // 等待所有任务完成后再关闭
        executor.setWaitForTasksToCompleteOnShutdown(true);

        // 等待时间(秒)
        executor.setAwaitTerminationSeconds(30);

        executor.initialize();

        return executor;
    }

    /**
     * Boss组线程池Bean (可选，用于Netty以外的场景)
     */
    @Bean("bossExecutor")
    public Executor bossExecutor() {
        log.info("初始化Boss线程池 bossExecutor");

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(bossGroup.getCorePoolSize());
        executor.setMaxPoolSize(bossGroup.getMaxPoolSize());
        executor.setQueueCapacity(bossGroup.getQueueCapacity());
        executor.setThreadNamePrefix(bossGroup.getNamePrefix());
        executor.setKeepAliveSeconds(60);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(30);
        executor.initialize();

        return executor;
    }

    /**
     * Worker组线程池Bean (可选，用于Netty以外的场景)
     */
    @Bean("workerExecutor")
    public Executor workerExecutor() {
        log.info("初始化Worker线程池 workerExecutor");

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(workerGroup.getCorePoolSize());
        executor.setMaxPoolSize(workerGroup.getMaxPoolSize());
        executor.setQueueCapacity(workerGroup.getQueueCapacity());
        executor.setThreadNamePrefix(workerGroup.getNamePrefix());
        executor.setKeepAliveSeconds(60);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(30);
        executor.initialize();

        return executor;
    }

    // ==================== Getters and Setters ====================

    public ExecutorProperties getBossGroup() {
        return bossGroup;
    }

    public void setBossGroup(ExecutorProperties bossGroup) {
        this.bossGroup = bossGroup;
    }

    public ExecutorProperties getWorkerGroup() {
        return workerGroup;
    }

    public void setWorkerGroup(ExecutorProperties workerGroup) {
        this.workerGroup = workerGroup;
    }

    public ExecutorProperties getMsgExec() {
        return msgExec;
    }

    public void setMsgExec(ExecutorProperties msgExec) {
        this.msgExec = msgExec;
    }

    /**
     * 线程池属性配置类
     */
    public static class ExecutorProperties {

        /**
         * 核心线程数
         */
        private int corePoolSize = 4;

        /**
         * 最大线程数
         */
        private int maxPoolSize = 8;

        /**
         * 队列容量
         */
        private int queueCapacity = 1000;

        /**
         * 线程名前缀
         */
        private String namePrefix = "pool-";

        public int getCorePoolSize() {
            return corePoolSize;
        }

        public void setCorePoolSize(int corePoolSize) {
            this.corePoolSize = corePoolSize;
        }

        public int getMaxPoolSize() {
            return maxPoolSize;
        }

        public void setMaxPoolSize(int maxPoolSize) {
            this.maxPoolSize = maxPoolSize;
        }

        public int getQueueCapacity() {
            return queueCapacity;
        }

        public void setQueueCapacity(int queueCapacity) {
            this.queueCapacity = queueCapacity;
        }

        public String getNamePrefix() {
            return namePrefix;
        }

        public void setNamePrefix(String namePrefix) {
            this.namePrefix = namePrefix;
        }
    }
}
