package ex7;

import ch.usi.dag.disl.annotation.After;
import ch.usi.dag.disl.annotation.Before;
import ch.usi.dag.disl.dynamiccontext.DynamicContext;
import ch.usi.dag.disl.marker.BodyMarker;
import ch.usi.dag.disl.marker.BytecodeMarker;
import ch.usi.dag.disl.staticcontext.ClassStaticContext;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;


public class Instrumentation {
    @Before(marker = BytecodeMarker.class, args = "MONITORENTER", scope = "ex7.MainThread.*")
    static void handleMonitorAccess(final DynamicContext dc) {
        final Object monitor = dc.getStackValue(0, Object.class);
        Profiler.countMonitorAccess(monitor);
    }

    @After(marker = BodyMarker.class, scope = "ex7.MainThread.*", guard = IsSynchronizedMethodGuard.class)
    static void handledSynchronizedAccess(final MethodStaticContext mc, final DynamicContext dc, final ClassStaticContext cc) {
        if (mc.isMethodStatic()) {
            try {
                Class<?> methodClass = Class.forName(cc.getName());
                Profiler.countMonitorAccess(methodClass);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException("Class " + cc.getName() + " not found");
            }

        } else {
            Profiler.countMonitorAccess(dc.getThis());
        }
    }


}
