package org.springblade.modules.nh.factory.common;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;
import java.util.Map;

@Slf4j
public abstract class EachRunner<T> {

    /**
     * @param interval 单位秒
     */
    public void start(List<T> val, String label, Long interval, Map<String, Object> ctx) {
        long s = System.currentTimeMillis();
        log.info("start long task {} =======================", label);
        long lastTime = s;
        for (T t : val) {
            if (interval != null && interval > 0) {
                long p = System.currentTimeMillis() - lastTime - interval * 1000;
                if (p < 0) {
                    sleepSilently(Math.abs(p));
                }
            }
            lastTime = System.currentTimeMillis();
            try {
                handle(t, ctx);
            } catch (Exception ex) {
                log.error("each runner handle error, label: {}", label, ex);
            }
        }
        log.info("end long task {} =======================, consumed: {}", label, System.currentTimeMillis() - s);
    }

    public abstract void handle(T val, Map<String, Object> ctx) throws IOException;

    private void sleepSilently(long t) {
        try {
            Thread.sleep(t);
        } catch (InterruptedException e) {
            // ignore
        }
    }

    public Runnable asyncStart(List<T> val, String label, Long interval, Map<String, Object> ctx) {
        return new Runnable() {
            @Override
            public void run() {
                start(val, label, interval, ctx);
            }
        };
    }
}
