package cn.yunzhixue.ability.center.examsprint.configuration;

import cn.yunzhixue.ability.center.examsprint.application.report.ExamSprintReportProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.time.Clock;
import java.util.concurrent.Executor;

@Configuration
@EnableConfigurationProperties(ExamSprintReportRuntimeConfiguration.BoundExamSprintReportProperties.class)
public class ExamSprintReportRuntimeConfiguration {

    @Bean
    public Clock systemClock() {
        return Clock.systemUTC();
    }

    @Bean
    @Primary
    public ExamSprintReportProperties examSprintReportProperties(BoundExamSprintReportProperties bound) {
        ExamSprintReportProperties properties = new ExamSprintReportProperties();
        properties.setRetention(bound.getRetention());
        properties.setDownloadExpiry(bound.getDownloadExpiry());
        properties.setCleanupIntervalMs(bound.getCleanupIntervalMs());
        properties.getAsync().setCorePoolSize(bound.getAsync().getCorePoolSize());
        properties.getAsync().setMaxPoolSize(bound.getAsync().getMaxPoolSize());
        properties.getAsync().setQueueCapacity(bound.getAsync().getQueueCapacity());
        properties.getStorage().setType(bound.getStorage().getType());
        properties.getStorage().setContainerName(bound.getStorage().getContainerName());
        properties.getStorage().setConnectionString(bound.getStorage().getConnectionString());
        properties.getStorage().setEndpoint(bound.getStorage().getEndpoint());
        properties.getStorage().setAccountName(bound.getStorage().getAccountName());
        properties.getStorage().setAccountKey(bound.getStorage().getAccountKey());
        properties.getStorage().setDownloadUrlPrefix(bound.getStorage().getDownloadUrlPrefix());
        return properties;
    }

    @Bean(name = "examSprintReportExecutor")
    public Executor examSprintReportExecutor(ExamSprintReportProperties properties) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setThreadNamePrefix("exam-sprint-report-");
        executor.setCorePoolSize(properties.getAsync().getCorePoolSize());
        executor.setMaxPoolSize(properties.getAsync().getMaxPoolSize());
        executor.setQueueCapacity(properties.getAsync().getQueueCapacity());
        executor.initialize();
        return executor;
    }

    @ConfigurationProperties(prefix = "ability.exam-sprint.report")
    public static class BoundExamSprintReportProperties extends ExamSprintReportProperties {
    }
}
