package io.delphiplatform.api.config;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

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

/**
 * Default TaskExecutor to be used by @Async annotated methods
 */
@Configuration
public class AsyncConfiguration implements AsyncConfigurer {

    @Value("${delphi.executor.core-pool-size}")
    public int corePoolSize = 24;
    @Value("${delphi.executor.max-pool-size}")
    public int maxPoolSize = 64;
    @Value("${delphi.executor.queue-capacity}")
    public int queueCapacity = 10;

    @Value("${delphi.executor-bt-query.core-pool-size}")
    public int btQueryCorePoolSize = 24;
    @Value("${delphi.executor-bt-query.max-pool-size}")
    public int btQueryMaxPoolSize = 64;
    @Value("${delphi.executor-bt-query.queue-capacity}")
    public int btQueryQueueCapacity = 10;

    @Override
    public Executor getAsyncExecutor() {
        return getThreadPoolTaskExecutor();
    }

    private ThreadPoolTaskExecutor getThreadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("API-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

    @Bean("btQueriesExecutor")
    public ThreadPoolTaskExecutor getBTQueriesExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(btQueryCorePoolSize);
        executor.setMaxPoolSize(btQueryMaxPoolSize);
        executor.setQueueCapacity(btQueryQueueCapacity);
        executor.setThreadNamePrefix("BT_QUERY-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}
