package br.ufrgs.inf.prosoft.tigris.monitoring.aspects;

import ca.uqac.lif.bullwinkle.BnfParser;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import java.io.IOException;

@Aspect
public class MonitorAspect {

    @Pointcut(
            //any execution except the own framework
            "(execution(!void *(..)) && !within(br.ufrgs.inf.prosoft..*) " +
                    //avoid calls from repository while serializing objects, it is necessary if a hash could not be used
                    "&& !cflow(call(* br.ufrgs.inf.prosoft.tigris.monitoring.storage..*(..))) " +
                    //conditional to enable and disable at runtime
                    "&& if())"
    )
    public static boolean anyCall() {
        return TigrisCoordinator.isEnabled();
    }

    private TigrisCoordinator tigrisCoordinator;

    public MonitorAspect() throws IOException, BnfParser.InvalidGrammarException {
        tigrisCoordinator = new TigrisCoordinator();
    }

    @Around("anyCall()")
    public Object aroundMethods(ProceedingJoinPoint joinPoint) throws Throwable {
        if (tigrisCoordinator.isAllowed(joinPoint)) {
            return tigrisCoordinator.process(joinPoint);
        } else {
            return joinPoint.proceed();
        }
    }
}