package org.tio.sitexxx.service.utils;

import org.tio.utils.Threads;
import org.tio.utils.thread.pool.DefaultThreadFactory;
import org.tio.utils.thread.pool.SynThreadPoolExecutor;

import java.util.concurrent.*;

/**
 * <pre>
 *    @author : vagrancy
 *    e-mail : 18050829067@163.com
 *    time   : 2025-12-03 09:43
 *    desc   : 应用线程
 * </pre>
 */
public class AppThreads {
    public static final int					AVAILABLE_PROCESSORS	= Runtime.getRuntime().availableProcessors();
    public static final int					CORE_POOL_SIZE			= AVAILABLE_PROCESSORS;
    public static final int					MAX_POOL_SIZE_FOR_TIO	= Integer.getInteger("TIO_MAX_POOL_SIZE_FOR_TIO", Math.max(CORE_POOL_SIZE * 3, 64));
    public static final int					MAX_POOL_SIZE_FOR_GROUP	= Integer.getInteger("TIO_MAX_POOL_SIZE_FOR_GROUP", Math.max(CORE_POOL_SIZE * 16, 256));
    public static final long				KEEP_ALIVE_TIME			= 60L;																					//360000L;
    @SuppressWarnings("unused")
    private static final int				QUEUE_CAPACITY			= 1000000;
    private static ThreadPoolExecutor groupExecutor			= null;
    private static SynThreadPoolExecutor	tioExecutor				= null;

    /**
     *
     * @return
     * @author tanyaowu
     */
    public static ThreadPoolExecutor getGroupExecutor() {
        if (groupExecutor != null) {
            return groupExecutor;
        }

        synchronized (org.tio.utils.Threads.class) {
            if (groupExecutor != null) {
                return groupExecutor;
            }

            int queueCapacity = 1024;
            BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(queueCapacity);
            String threadName = "tio-group";
            ThreadFactory factory = DefaultThreadFactory.getInstance(threadName, Thread.NORM_PRIORITY);
            groupExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE_FOR_GROUP, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
                    workQueue, factory, new TioRejectedExecutionHandler());
            groupExecutor.allowCoreThreadTimeOut(true);
            groupExecutor.prestartCoreThread();
            return groupExecutor;
        }
    }

    /**
     *
     * @return
     * @author tanyaowu
     */
    public static SynThreadPoolExecutor getExecutor() {
        if (tioExecutor != null) {
            return tioExecutor;
        }

        synchronized (Threads.class) {
            if (tioExecutor != null) {
                return tioExecutor;
            }

            int queueCapacity = 1024;
            BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(queueCapacity);
            String threadName = "tio-worker";
            ThreadFactory factory = DefaultThreadFactory.getInstance(threadName, Thread.NORM_PRIORITY);
            tioExecutor = new SynThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE_FOR_TIO, KEEP_ALIVE_TIME, workQueue,
                    factory, threadName, new TioRejectedExecutionHandler());

            tioExecutor.allowCoreThreadTimeOut(true); // 允许核心线程超时回收
            tioExecutor.prestartCoreThread();
            return tioExecutor;
        }
    }

    // 自定义拒绝策略：记录日志 + 返回错误给客户端
    public static class TioRejectedExecutionHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            System.out.println("TIO task rejected. Pool: {"+executor.getActiveCount()+"}, Queue: {"+executor.getQueue().size()+"}");
            // 3. 可选：放入降级队列 or 丢弃
        }
    }
}
