package cz.muni.fi.pa165.soccermanager.aop;

import cz.muni.fi.pa165.soccermanager.annotation.CredentialsEndpoint;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.CodeSignature;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@Log4j2
@Aspect
@Component
@RequiredArgsConstructor
public class LoggerAspect {

  @Before("execution(* cz.muni.fi.pa165.soccermanager.controllers..*.*(..) )")
  private void logIncomingRequest(JoinPoint joinPoint) {
    if (joinPoint.getSignature().getDeclaringType().getAnnotation(CredentialsEndpoint.class) == null) {
      String[] names = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
      Object[] args = joinPoint.getArgs();
      log.info(
          "Method {} executed at {} by user with username {}",
          joinPoint.getStaticPart().getSignature()::getName,
          joinPoint.getStaticPart().getSignature()::getDeclaringTypeName,
          SecurityContextHolder.getContext().getAuthentication()::getName
      );
      for (int i = 0; i < names.length; i++) {
        if (!(args[i] instanceof byte[])) {
          log.info("Method parameter '{}' with value of '{}'", names[i], args[i]);
        }
      }
    }
  }
}

