package cn.axzo.workflow.core.common.event;

import cn.axzo.workflow.core.repository.entity.ExtAxApiLog;
import cn.axzo.workflow.core.service.ExtAxApiLogService;
import cn.hutool.json.JSONUtil;
import com.google.common.base.Strings;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static cn.azxo.framework.common.constatns.Constants.CTX_LOG_ID_MDC;

/**
 * Api Log 记录表操作监听
 *
 * @author wangli
 * @since 2024/4/3 10:37
 */
@Component
@Slf4j
@RefreshScope
public class ApiLogListener implements ApplicationListener<ApiLogEvent> {

    @Value("${workflow.apiLog.enable: false}")
    private Boolean enable;
    @Resource
    private ExtAxApiLogService apiLogService;
    private static final List<String> EXCLUDE_URLS = new ArrayList<>();

    static {
        EXCLUDE_URLS.add("HealthCheckController.checkDeath()");
    }

    @SneakyThrows
    @Override
    @Async
    public void onApplicationEvent(ApiLogEvent event) {
        if (!enable || EXCLUDE_URLS.contains(event.getApiUrl())) {
            return;
        }
        rebuildTraceId(event);

        ExtAxApiLog apiLog = new ExtAxApiLog();
        apiLog.setTraceId(event.getTraceId());
        apiLog.setApiUrl(event.getApiUrl());
        apiLog.setRequestBody(JSONUtil.toJsonStr(event.getRequestBody()));
        apiLog.setResponseBody(JSONUtil.toJsonStr(event.getResponseBody()));
        apiLog.setTakeTime(event.getTakeTime());
        apiLog.setType(event.getType());
        apiLogService.insert(apiLog);
    }

    private static void rebuildTraceId(ApiLogEvent event) {
        if (Strings.isNullOrEmpty(event.getTraceId())) {
            String traceId = Strings.isNullOrEmpty(event.getTraceId())
                    ? UUID.randomUUID().toString().replaceAll("-", "") : event.getTraceId();
            MDC.put(CTX_LOG_ID_MDC, traceId);
            event.setTraceId(traceId);
        }
    }
}
