package com.caliverse.admin.global.common.aspect;

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.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Slf4j
public class LoggingAspect {
//    private static final Logger log = LoggerFactory.getLogger("METHOD_LOGGER");

    @Pointcut("@within(org.springframework.stereotype.Component) || " +
            "@within(org.springframework.stereotype.Service) || " +
            "@within(org.springframework.stereotype.Repository) || " +
            "@within(org.springframework.stereotype.Controller)")
    public void pointcut() {}

    @Pointcut("within(com.caliverse.admin.domain.api..*) || " +
            "within(com.caliverse.admin.domain.service..*) || " +
            "within(com.caliverse.admin.scheduler..*) || " +
            "within(com.caliverse.admin.dynamodb.repository..*) || " +
            "within(com.caliverse.admin.dynamodb.service..*)")
    public void specificPackages() {}

    @Around("pointcut() && specificPackages()")
    public Object logging(ProceedingJoinPoint pjp) throws Throwable {
        String methodName = pjp.getSignature().getName();
        String className = pjp.getSignature().getDeclaringTypeName();

        String format = String.format("%s.%s",className,methodName);
        MDC.put("method", methodName);

        try {
            log.info("{} method start", format);
            Object result = pjp.proceed();
            log.info("{} method end", format);
            return result;
        } catch (Exception e) {
            log.error("[{}] method error: {}", methodName, e.getMessage());
            throw e;
        } finally {
            MDC.remove("method");
        }
    }
}
