package org.example.seed.logger;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.concurrent.Callable;

/**
 * Created by Ricardo Pina Arellano on 21/01/2017.
 */
@Aspect
@Component
public class RESTAspectLogger {

    private final Logger log = LoggerFactory.getLogger(this.getClass());
    private final ObjectMapper objectMapper = new ObjectMapper();

    public RESTAspectLogger() {
        this.objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
    }

    @Pointcut("within(org.example.seed.rest..*)")
    public void rest() {
    }

    @Pointcut("execution(public * *(..))")
    protected void allMethod() {
    }

    @Before("rest() && allMethod()")
    public void logBefore(JoinPoint joinPoint) throws JsonProcessingException {

        log.warn("Entering in Method :  " + joinPoint.getSignature().getName());
        log.warn("Class Name :  " + joinPoint.getSignature().getDeclaringTypeName());
        log.warn("Arguments :  " + this.objectMapper.writeValueAsString(joinPoint.getArgs()));
    }

    @AfterReturning(pointcut = "rest() && allMethod()", returning = "callable")
    public void logAfter(JoinPoint joinPoint, Object callable) throws Exception {

        final Callable<Object> response = (Callable<Object>) callable;

        log.warn("Method Return value : " + this.objectMapper.writeValueAsString(response.call()));
    }

    @AfterThrowing(pointcut = "rest() && allMethod()", throwing = "exception")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable exception) {

        log.error("An exception has been thrown in " + joinPoint.getSignature().getName() + " ()");
        log.error("Cause : " + exception.getCause());
    }

    @Around("rest() && allMethod()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {

        final long start = System.currentTimeMillis();

        try {
            final String className = joinPoint.getSignature().getDeclaringTypeName();
            final String methodName = joinPoint.getSignature().getName();
            final Object result = joinPoint.proceed();
            final long elapsedTime = System.currentTimeMillis() - start;

            log.warn("Method " + className + "." + methodName + " ()" + " execution time : " + elapsedTime + " ms");

            return result;
        } catch (final IllegalArgumentException e) {
            log.error("Illegal argument " + Arrays.toString(joinPoint.getArgs()) + " in " + joinPoint.getSignature().getName() + "()");

            throw e;
        }
    }
}

@@ -598,18 +598,16 @@
 gger %7B%0A%0A
-  
   privat
@@ -669,18 +669,16 @@
 ass());%0A
-  
   privat
@@ -736,18 +736,16 @@
 r();%0A%0A  
- 
- 
 public R
@@ -768,20 +768,16 @@
 ) %7B%0A    
-   
- 
 this.obj
@@ -830,25 +830,21 @@
 UTPUT);%0A
-  
   %7D%0A%0A
-  
   @Point
@@ -879,26 +879,24 @@
 .rest..*)%22)%0A
-  
   public voi
@@ -905,26 +905,20 @@
 rest() %7B
-%0A   
  %7D%0A%0A
-  
   @Point
@@ -950,18 +950,16 @@
 (..))%22)%0A
-  
   protec
@@ -980,26 +980,20 @@
 thod() %7B
-%0A   
  %7D%0A%0A
-  
   @Befor
@@ -1011,34 +1011,32 @@
 & allMethod()%22)%0A
-  
   public void lo
@@ -1094,28 +1094,24 @@
 xception %7B%0A%0A
-    
     log.warn
@@ -1167,36 +1167,32 @@
 e().getName());%0A
-    
     log.warn(%22Cl
@@ -1257,20 +1257,16 @@
 ame());%0A
-    
     log.
@@ -1342,39 +1342,35 @@
 .getArgs()));%0A  
- 
- 
 %7D%0A%0A
-  
   @AfterReturnin
@@ -1431,18 +1431,16 @@
 lable%22)%0A
-  
   public
@@ -1508,28 +1508,24 @@
 xception %7B%0A%0A
-    
     final Ca
@@ -1580,20 +1580,16 @@
 lable;%0A%0A
-    
     log.
@@ -1672,33 +1672,29 @@
 e.call()));%0A
-  
   %7D%0A%0A
-  
   @AfterThro
@@ -1756,26 +1756,24 @@
 ception%22)%0A  
- 
- 
 public void 
@@ -1830,28 +1830,24 @@
 ception) %7B%0A%0A
-    
     log.erro
@@ -1930,20 +1930,16 @@
 %22 ()%22);%0A
-    
     log.
@@ -1984,17 +1984,13 @@
 ));%0A
-  
   %7D%0A%0A
-  
   @A
@@ -2020,18 +2020,16 @@
 hod()%22)%0A
-  
   public
@@ -2097,28 +2097,24 @@
 able %7B%0A%0A    
-   
- 
 final long s
@@ -2145,28 +2145,24 @@
 eMillis();%0A%0A
-    
     try %7B%0A  
@@ -2161,30 +2161,24 @@
 try %7B%0A      
-    
-  
 final String
@@ -2231,38 +2231,32 @@
 ringTypeName();%0A
-      
       final Stri
@@ -2309,30 +2309,24 @@
 me();%0A      
- 
-     
 final Object
@@ -2362,22 +2362,16 @@
 ;%0A      
-    
-  
 final lo
@@ -2424,22 +2424,16 @@
 start;%0A%0A
-      
       lo
@@ -2532,30 +2532,24 @@
  + %22 ms%22);%0A%0A
-      
       return
@@ -2557,20 +2557,16 @@
 result;%0A
-    
     %7D ca
@@ -2606,22 +2606,16 @@
 on e) %7B%0A
-      
       lo
@@ -2737,22 +2737,16 @@
 %22()%22);%0A%0A
-      
       th
@@ -2760,16 +2760,10 @@
     
-    %7D%0A  
+%7D%0A
   %7D%0A

set 2 spase identation