package cn.axzo.workflow.core.engine.id;


import org.flowable.common.engine.impl.cfg.IdGenerator;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 基于时间的编号生成器
 *
 * @author wangli
 * @since 2023/10/31 10:41
 */
public class TimeBasedIdGenerator implements IdGenerator {

    private static final long MAX_SEQUENCE = 1000_000_000L;
    private static final AtomicLong sequence = new AtomicLong(0);
    private static volatile String lastTimestamp = "";

    @Override
    public synchronized String getNextId() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmm");
        String timestamp = dateFormat.format(new Date());

        if (timestamp.equals(lastTimestamp)) {
            long currentSequence = sequence.incrementAndGet() % MAX_SEQUENCE;
            if (currentSequence == 0) {
                // 如果递增数已达到最大值，则等待下一毫秒
                timestamp = tilNextTimestamp(timestamp, dateFormat);
            }
        } else {
            sequence.set(0);
        }

        lastTimestamp = timestamp;

        return timestamp + String.format("%09d", sequence.get());
    }

    private String tilNextTimestamp(String lastTimestamp, SimpleDateFormat dateFormat) {
        String timestamp = dateFormat.format(new Date());
        while (timestamp.equals(lastTimestamp)) {
            timestamp = dateFormat.format(new Date());
        }
        return timestamp;
    }

}
