package com.flightticket.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.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/**
 * Configuration for asynchronous processing in the API Usage Billing System.
 * 
 * This configuration enables async execution for usage logging operations,
 * ensuring that API call interception does not block the main request flow.
 * 
 * Configuration properties are externalized in application.yml under billing.async.*
 * allowing for environment-specific tuning without code changes.
 * 
 * Requirements: 1.6, 5.1
 */
@Configuration
@EnableAsync
public class AsyncConfig {
    
    @Value("${billing.async.core-pool-size:5}")
    private int corePoolSize;
    
    @Value("${billing.async.max-pool-size:10}")
    private int maxPoolSize;
    
    @Value("${billing.async.queue-capacity:100}")
    private int queueCapacity;
    
    @Value("${billing.async.thread-name-prefix:usage-logger-}")
    private String threadNamePrefix;
    
    /**
     * Configures the thread pool task executor for asynchronous usage logging.
     * 
     * Pool Configuration (configurable via application.yml):
     * - Core Pool Size: Minimum threads always alive (default: 5)
     * - Max Pool Size: Maximum threads under load (default: 10)
     * - Queue Capacity: Tasks queued when all threads are busy (default: 100)
     * - Thread Name Prefix: For easy identification in logs (default: "usage-logger-")
     * 
     * This configuration ensures:
     * - Non-blocking API responses (async logging)
     * - Efficient resource utilization (bounded thread pool)
     * - Graceful handling of load spikes (queue capacity)
     * - Easy debugging (named threads)
     * - Environment-specific tuning (externalized configuration)
     * 
     * @return configured Executor for async task execution
     */
    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix(threadNamePrefix);
        executor.initialize();
        return executor;
    }
}
