package shop.alien.store.config;

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.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 异步任务配置类
 * 用于配置异步任务的线程池
 *
 * @author assistant
 * @since 2025-12-19
 */
@Configuration
@EnableAsync
public class AsyncConfig {

    /**
     * 配置异步任务执行器
     * 用于执行AI审核等异步任务
     *
     * @return 异步任务执行器
     */
    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(5);
        // 最大线程数
        executor.setMaxPoolSize(10);
        // 队列容量
        executor.setQueueCapacity(100);
        // 线程名前缀
        executor.setThreadNamePrefix("async-task-");
        // 拒绝策略：调用者运行策略
        executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 等待时间
        executor.setAwaitTerminationSeconds(60);
        executor.initialize();
        return executor;
    }

    @Bean(name = "commonVideoTaskExecutor")
    public ExecutorService initExecutor() {
        // 核心参数根据业务调整，IO密集型任务线程数可设为CPU核心数*2~4
        int corePoolSize = Runtime.getRuntime().availableProcessors() * 2;
        int maxPoolSize = Runtime.getRuntime().availableProcessors() * 4;
        ExecutorService  videoAuditExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maxPoolSize,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(500), // 任务队列，避免无界队列溢出
                new ThreadFactory() {
                    private int count = 0;

                    @Override
                    public Thread newThread(Runnable r) {
                        Thread t = new Thread(r);
                        t.setName("video-audit-" + count++); // 自定义线程名，便于排查
                        return t;
                    }
                },
                // 任务拒绝策略：记录日志+调用者线程兜底（避免任务丢失）
                new ThreadPoolExecutor.CallerRunsPolicy() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                        super.rejectedExecution(r, e);
                    }
                }
        );
        return videoAuditExecutor;
    }

    /**
     * 图片审核专用线程池，用于门店图片等并行审核，避免每次请求创建新线程池
     */
    @Bean(name = "imgAuditExecutor")
    public ExecutorService imgAuditExecutor() {
        int core = Math.max(4, Runtime.getRuntime().availableProcessors() * 2);
        int max = Math.max(8, Runtime.getRuntime().availableProcessors() * 4);
        AtomicInteger counter = new AtomicInteger(0);
        return new ThreadPoolExecutor(
                core,
                max,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(300),
                r -> {
                    Thread t = new Thread(r);
                    t.setName("img-audit-" + counter.getAndIncrement());
                    return t;
                },
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }
}

