package com.jay.monitor.data.server.factory.generate;

import com.jay.monitor.data.server.enums.DataSplitType;
import com.jay.monitor.data.server.factory.ChangeConsumer;
import com.jay.monitor.data.server.factory.IdGenerateService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Module 编号生成器
 * @Description 根据天生成编号
 * @Author liukaixiong
 * @Date 2020/11/5 15:04
 */
@Component
public class DayIdGenerate implements IdGenerateService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 防止在做天分割的时候，获取当前的时间戳不对。
     */
    private final long delaySecond = 300 * 1000L;

    /**
     * 一天的秒
     */
    private final long DAY = 24 * 3600 * 1000L;
    /**
     * 算天的时候可能要考虑时区,得先加8小时
     */
    private final Long timeZone = 8 * 3600 * 1000L;

    private SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");

    private volatile long m_timestamp = getDayTimestamp();

    private volatile String defaultId = resetCounter(m_timestamp);

    public void setM_timestamp(long m_timestamp) {
        this.m_timestamp = m_timestamp;
    }

    public void setDefaultId(String defaultId) {
        this.defaultId = defaultId;
    }

    public long getM_timestamp() {
        return m_timestamp;
    }

    public String getDefaultId() {
        return defaultId;
    }

    protected long getDayTimestamp() {
        long timestamp = System.currentTimeMillis() + timeZone;
        return timestamp / DAY;
    }

    private String resetCounter(long timestamp) {
        this.m_timestamp = timestamp;
        // 这里是为了防止出现,获取当前时间戳 刚好卡在昨天末尾的那个点上.
        long currentTimeMillis = System.currentTimeMillis();
        long currentTimestamp = currentTimeMillis + delaySecond;
        this.defaultId = sdf.format(new Date(currentTimestamp));
        logger.info("重置Day的编号! 当前时间戳:" + currentTimeMillis + "\t 累加后的时间戳:" + currentTimestamp + " 默认编号:" + this.defaultId);
        return this.defaultId;
    }

    @Override
    public DataSplitType splitType() {
        return DataSplitType.DAY;
    }

    @Override
    public String getCurrentId(ChangeConsumer<String> consumer) {
        long timestamp = getDayTimestamp();
        String id = defaultId;
        if (timestamp != m_timestamp) {
            synchronized (this) {
                if (timestamp != m_timestamp) {
                    id = resetCounter(timestamp);
                    consumer.accept(id);
                }
            }
        }
        return id;
    }

    @Override
    public String getNextId(String id) {
        return null;
    }
}
