package com.storlead.sales.mail.util;

import com.storlead.framework.common.thread.ThreadPoolUtil;
import lombok.extern.log4j.Log4j2;

import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @program: sp-sales-platform
 * @description:
 * @author: chenkq
 * @create: 2024-08-26 16:27
 */
@Log4j2
public class ReceiveMailQueueThreadPool {


    private static volatile ReceiveMailQueueThreadPool instance;

    // 用于存储每个人的任务队列
    private final Map<String, Queue<Runnable>> taskMap;

    public Boolean getTaskInProgressByMail(String mailAddress) {
        return taskInProgress.getOrDefault(mailAddress, false);
    }

    // 用于存储每个人当前是否有任务在进行中
    private final Map<String, Boolean> taskInProgress;

    // 线程池，用于执行任务
    private final ThreadPoolExecutor executorService;

    public ReceiveMailQueueThreadPool() {
        this.taskMap = new HashMap<>();
        this.taskInProgress = new HashMap<>();
        this.executorService = ThreadPoolUtil.getThreadExecutor();
    }

    // 双重检查锁的单例获取方法
    public static ReceiveMailQueueThreadPool getInstance() {
        if (instance == null) {
            synchronized (ReceiveMailQueueThreadPool.class) {
                if (instance == null) {
                    instance = new ReceiveMailQueueThreadPool();
                }
            }
        }
        return instance;
    }

    // 添加任务到某个人的队列
    public synchronized void addTask(String person, Runnable task) {
        if (Objects.nonNull(taskMap) && Objects.nonNull(taskMap.get(person))) {
            return; // 该人有任务正在进行中
        }
        taskMap.putIfAbsent(person, new LinkedList<>());
        taskMap.get(person).offer(task);
        taskInProgress.putIfAbsent(person, false);
        processNextTask(person);
    }

    // 处理某个人的下一个任务
    private synchronized void processNextTask(String person) {
        if (taskInProgress.getOrDefault(person, false)) {
            return; // 该人有任务正在进行中
        }

        Queue<Runnable> queue = taskMap.get(person);
        if (queue == null || queue.isEmpty()) {
            log.error("没有任务了--"+person);
            return; // 无任务可处理
        }

        Runnable task = queue.poll();
        taskInProgress.put(person, true);
        executorService.submit(() -> {
            try {
                task.run(); // 执行任务
            } finally {
                taskCompleted(person); // 标记任务完成并处理下一个任务
            }
        });
    }

    // 标记任务完成
    public synchronized void taskCompleted(String person) {
        taskInProgress.put(person, false);
        taskMap.remove(person);
        processNextTask(person);
    }

    // 关闭线程池
    public void shutdown() {
        executorService.shutdown();
    }
}
