package org.springblade.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;

public class MultiAsyncTaskRunner implements AsyncTaskRunner {

    private final Runnable taskCleaner;
    private volatile boolean run;
    private static final Logger log = LoggerFactory.getLogger(MultiAsyncTaskRunner.class);

    public MultiAsyncTaskRunner(String taskId, Runnable taskCleaner) {
        this.taskCleaner = taskCleaner;
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (!run) {
                    log.error("task might hang, task.id: {}", taskId, new Exception());
                    taskCleaner.run();
                }
            }
        }, 30 * 1000);
    }

    @Override
    public void run(List<Runnable> runnableList) {
        run = true;
        if (CollectionUtils.isEmpty(runnableList)) {
            taskCleaner.run();
            return;
        }
        CountDownLatch latch = new CountDownLatch(runnableList.size());
        for (Runnable runnable : runnableList) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        runnable.run();
                    } finally {
                        latch.countDown();
                    }
                }
            }).start();
        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            // ignore
        } finally {
            taskCleaner.run();
        }
    }
}
