package com.lanyuanxiaoyao.service.common.utils;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.lanyuanxiaoyao.service.common.Constants;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.MDC;

/**
 * 日志相关
 *
 * @author ZhangJiacheng
 * @date 2023-12-25
 */
public class LogHelper {
    private static String generateLog(LogPoint point, String template, Object[] args) {
        if (ObjectUtil.isEmpty(template)) {
            return point.toString();
        }
        if (ObjectUtil.isEmpty(args)) {
            return point + " " + template;
        }
        Object[] items = new Object[args.length + 1];
        items[0] = point;
        System.arraycopy(args, 0, items, 1, args.length);
        return StrUtil.format("{} " + template, items);
    }

    public static void info(Logger logger, LogPoint point) {
        logger.info(generateLog(point, null, null));
    }

    public static void info(Logger logger, LogPoint point, String template) {
        logger.info(generateLog(point, template, null));
    }

    public static void info(Logger logger, LogPoint point, String template, Object... args) {
        logger.info(generateLog(point, template, args));
    }

    public static void debug(Logger logger, LogPoint point, String template, Object... args) {
        logger.debug(generateLog(point, template, args));
    }

    public static void warn(Logger logger, LogPoint point, String template, Object... args) {
        logger.warn(generateLog(point, template, args));
    }

    public static void error(Logger logger, LogPoint point, String template, Object... args) {
        logger.error(generateLog(point, template, args));
    }

    public static void setMdc(Map<String, String> mdcList) {
        mdcList.forEach(MDC::put);
    }

    public static void setMdc(String... items) {
        if (items.length % 2 != 0) {
            throw new IllegalArgumentException("Items must key-value");
        }
        MapBuilder<String, String> builder = MapUtil.builder();
        for (int i = 0, j = 1; j < items.length; i++, j++) {
            builder.put(items[i], items[j]);
        }
        setMdc(builder.build());
    }

    public static void removeMdc(List<String> mdcList) {
        mdcList.forEach(MDC::remove);
    }

    public static void removeMdc(String... names) {
        removeMdc(ListUtil.of(names));
    }

    public static void setMdcFlinkJobAndAlias(Long flinkJobId, String alias) {
        setMdc(MapUtil.<String, String>builder()
                .put(Constants.LOG_FLINK_JOB_ID_LABEL, flinkJobId.toString())
                .put(Constants.LOG_ALIAS_LABEL, alias)
                .build());
    }

    public static void removeMdcFlinkJobAndAlias(Long flinkJobId, String alias) {
        removeMdc(ListUtil.of(Constants.LOG_FLINK_JOB_ID_LABEL, Constants.LOG_ALIAS_LABEL));
    }

    public enum LogPoint {
        PULSAR_SOURCE_CHECKPOINT_INITIAL(100),
        PULSAR_SOURCE_CHECKPOINT_INITIAL_MESSAGE_ID(101),

        MESSAGE_ID_EMPTY(1),
        CHECKPOINT_INITIAL(2),
        CHECKPOINT_INITIAL_MESSAGE_ID(3),
        PULSAR_SOURCE_BOOTSTRAP_MESSAGE_ID(4),
        PULSAR_SOURCE_BOOTSTRAP_GET_MESSAGE_ERROR(5),
        FIELD_TYPE_NOT_FOUND(6),
        VERSION_UPDATE(7),
        CHECKPOINT_START(8),
        CHECKPOINT_COMPLETE(9);

        private final Integer code;

        LogPoint(Integer code) {
            this.code = code;
        }

        @Override
        public String toString() {
            return String.format("LOP-%06d", code);
        }
    }
}
