package com.yxcheng.token.common.template;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Instant;

public abstract class ApiTemplate<T> {

    private static final String SUCCEED_POSTFIX = "_SUCCEED";
    private static final String FAILED_POSTFIX = "_FAILED";
    protected Logger logger = LoggerFactory.getLogger(getClass());
    protected String monitorKey;

    protected ApiTemplate(String monitorKey) {
        this.monitorKey = monitorKey;
    }

    protected void checkParams() {
    }

    protected abstract T process() throws Exception;

    protected void onFinish() {
    }

    protected void onSuccess() {
    }

    protected void onError(Throwable e) {
    }

    public T execute() {

        try {
            checkParams();
        } catch (IllegalArgumentException e) {
            logger.debug("check param failed", e);
            throw e;
        }

        Instant start = Instant.now();
        try {
            T result = process();
            onSuccess();
            Instant end = Instant.now();
            long duration = end.toEpochMilli() - start.toEpochMilli();
            logger.info("{} finished,cost:{}ms",monitorKey, duration);
            return result;
        } catch (Throwable e) {
            Instant end = Instant.now();
            long duration = end.toEpochMilli() - start.toEpochMilli();
            logger.warn("unexpected error while execute", e);
            onError(e);
            throw new RuntimeException("unexpected error", e);
        } finally {
            Instant end = Instant.now();
            onFinish();
        }
    }
}
