package dst.ass2.aop.logging;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import java.lang.reflect.Field;
import java.util.logging.Logger;

@Aspect
public class LoggingAspect {
    @Around("execution(* dst.ass2.aop.IPluginExecutable.execute(..)) && !@annotation(Invisible)")
    public Object around(ProceedingJoinPoint point) {
        //try to get logger, if one exists.
        Logger logger = null;
        for (Field f : point.getTarget().getClass().getDeclaredFields()) {
            if (f.getType().isAssignableFrom(Logger.class)) {
                try {
                    boolean accessible = f.isAccessible();
                    f.setAccessible(true);
                    logger = (Logger) f.get(point.getTarget());
                    f.setAccessible(accessible);
                } catch (IllegalAccessException ignored) {
                }
            }
        }

        //log before
        if (logger != null) {
            logger.info("Plugin " + point.getTarget().getClass() + " started to execute");
        } else {
            System.out.println("Plugin " + point.getTarget().getClass() + " started to execute");
        }

        //execute actual function
        Object result = null;
        try {
            result = point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        // log after.
        if (logger != null) {
            logger.info("Plugin " + point.getTarget().getClass() + " is finished");
        } else {
            System.out.println("Plugin " + point.getTarget().getClass() + " is finished");
        }
        return result;
    }
}
