package com.its.vds.stat.server.aspect;

import com.its.vds.stat.server.annotation.ProcessingElapsed;
import com.its.vds.stat.server.utils.LogUtils;
import com.its.vds.stat.server.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class LoggingAspect extends AbstractLoggingAspect {

    @Around("@annotation(com.its.vds.stat.server.annotation.ProcessingElapsed)")
    public Object aspectProcessingElapsedTime(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        ProcessingElapsed annotation = signature.getMethod().getAnnotation(ProcessingElapsed.class);

        String type = annotation.type();  // 기본값 "-----" 사용됨
        String processName = annotation.name();  // 기본값 "UNKNOWN_PROCESS" 사용됨

        if (annotation.starting()) {
            log.info("**>> {} {}: [{}]", type, LogUtils.elapsedLogLength(processName + " Start", type.length()), TimeUtils.getCurrentTimeString());
        }

        try {
            final long start = System.currentTimeMillis();
            Object proceed = joinPoint.proceed();
            long executionTime = System.currentTimeMillis() - start;
            if (annotation.ending()) {
                log.info("<<** {} {}", type, LogUtils.elapsedLogLength(processName + " End", executionTime, type.length()));
            }
            return proceed;
        }
        catch (InterruptedException e) {
            log.error("aspectProcessingElapsedTime: Thread interrupted", e);
            throw e;  // 재던지기
        }
    }

}
