package com.base.core;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

@Component
public class ThreadToolTemplate<T> {

    private final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

    public ThreadToolTemplate(){
        executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
        executor.setMaxPoolSize(executor.getCorePoolSize()*2);
        executor.setThreadFactory(new AccessThreadFactory());
        executor.setThreadNamePrefix("AccessThreadPool");
        executor.setKeepAliveSeconds(3);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        executor.initialize();
    }

    public void executeTask(Runnable runnable){
        executor.execute(runnable);
    }

    public Future<T> submitTask(Callable<T> task){
        return executor.submit(task);
    }

    public List<?> synAndListGet(List<Future<T>> list){
        List<?> res = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        list.forEach(e-> {
            try {
                Object o = e.get();
                if (o!=null){
                    res.addAll((List)o);
                }
            } catch (InterruptedException | ExecutionException ex) {
                ex.printStackTrace();
            }
        });
        return res;
    }
}