package com.fs.test;

import com.fs.FsUserAppApplication;
import com.fs.common.constant.RedisConstant;
import com.fs.common.core.redis.service.StockDeductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 50万高并发库存扣减测试
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = FsUserAppApplication.class)
@RequiredArgsConstructor
@Slf4j
public class StockDeductTest {

    @Autowired
    private StockDeductService stockDeductService;

    // 商品ID
    private static final Long PRODUCT_ID = 1001L;
    // 初始库存（模拟5万库存，应对50万并发扣减）
    private static final Integer INIT_STOCK = 5000;
    // 总请求数（50万）
    private static final int TOTAL_REQUESTS = 50000;

    /**
     * 模拟50万高并发库存扣减
     */
    @Test
    public void testHighConcurrencyDeduct() throws InterruptedException, ExecutionException {
        stockDeductService.initStock(PRODUCT_ID, 1L, INIT_STOCK);
        // Java 8 ExecutorService 线程池（固定线程池，适配高并发）
        ExecutorService executorService = createHighConcurrencyPool();

        // 存储所有异步任务结果
        List<CompletableFuture<Boolean>> futureList = new ArrayList<>();

        // 提交50万请求
        for (int i = 0; i < TOTAL_REQUESTS; i++) {
//            futureList.add(stockDeductService.deductStockAsync(PRODUCT_ID, 1L, (long) i));
        }

        // 等待所有任务完成（Java 8 CompletableFuture 批量处理）
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                futureList.toArray(new CompletableFuture[0])
        );
        allFutures.get();

        // 统计结果
        long successCount = futureList.stream()
                .map(future -> {
                    try {
                        return future.get();
                    } catch (Exception e) {
                        return false;
                    }
                })
                .filter(Boolean::booleanValue)
                .count();

        // 打印结果
        System.out.println("======================================");
        System.out.println("50万高并发库存扣减测试完成");
        System.out.println("成功扣减次数：" + successCount);
        System.out.println("失败扣减次数：" + (TOTAL_REQUESTS - successCount));
        System.out.println("最终剩余库存：" + stockDeductService.redisTemplate.opsForValue().get(RedisConstant.STOCK_KEY_PREFIX + PRODUCT_ID));
        System.out.println("======================================");

        // 关闭线程池
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES);
    }



    private static ExecutorService createHighConcurrencyPool() {
        int corePoolSize = Runtime.getRuntime().availableProcessors() * 2; // CPU核心数*2
        int maximumPoolSize = 200; // 最大线程数，根据服务器配置调整
        long keepAliveTime = 60L;
        // 用SynchronousQueue，直接提交任务，避免队列积压
        BlockingQueue<Runnable> workQueue = new SynchronousQueue<>();
        // 拒绝策略：丢弃最老的任务，避免OOM
        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();

        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                workQueue,
                new ThreadPoolExecutor.CallerRunsPolicy() // 兜底：主线程执行，避免任务丢失
        );
    }
}