package com.gentics.spring.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
@Scope("singleton")
public class TimeMeasureAspect {

	private static Logger log = Logger.getLogger(TimeMeasureAspect.class);

	private StopWatch findWatch = new StopWatch("Find bugs stop watch");

	private StopWatch createWatch = new StopWatch("Create bugs stop watch");

	@Around("execution(* com.gentics.spring.controller.BugController.find*(..))")
	private Object measureFindTime(ProceedingJoinPoint pjp) throws Throwable {

		log.debug("starting time measurement for find bug. Signature name: " + pjp.getSignature().getName());
		findWatch.start();

		Object returnValue = null;

		try {
			returnValue = pjp.proceed();
		} catch (Exception e) {
			// we catch all exceptions here in order to stop the watch in any
			// case
			log.error("Oooops, something went wrong with the method " + pjp.getSignature().getName(), e);
			throw e;
		} finally {
			findWatch.stop();
			log.debug("Execution of method " + pjp.getSignature().getName() + " took " + findWatch.getLastTaskTimeMillis());
		}

		return returnValue;
	}

	@Around("execution(* com.gentics.spring.controller.BugController.create(..))")
	private Object measureCreateTime(ProceedingJoinPoint pjp) throws Throwable {

		log.debug("starting time measurement for create bug. Signature name: " + pjp.getSignature().getName());
		createWatch.start();

		Object returnValue = null;

		try {
			returnValue = pjp.proceed();
		} catch (Exception e) {
			// we catch all exceptions here in order to stop the watch in any
			// case
			log.error("Oooops, something went wrong with the method " + pjp.getSignature().getName(), e);
			throw e;
		} finally {
			createWatch.stop();
			log.debug("Execution of method " + pjp.getSignature().getName() + " took " + createWatch.getLastTaskTimeMillis());
		}

		return returnValue;
	}

	public TimeMeasurement getTimeDetails() {
		return new TimeMeasurement(findWatch.getTotalTimeMillis(), createWatch.getTotalTimeMillis());
	}

}

@@ -494,141 +494,85 @@
 ate 
-StopWatch findWatch = new StopWatch(%22Find bugs stop watch%22);%0A%0A%09private StopWatch createWatch = new StopWatch(%22Create bugs stop watch%22
+Long findTotalTime = new Long(0);%0A%0A%09private Long createTotalTime = new Long(0
 );%0A%0A
@@ -831,16 +831,113 @@
 ame());%0A
+%09%09StopWatch findWatch = new StopWatch(%22Measure time of method %22 + pjp.getSignature().getName());%0A
 %09%09findWa
@@ -1378,32 +1378,87 @@
 kTimeMillis());%0A
+%09%09%09findTotalTime += findWatch.getLastTaskTimeMillis();%0A
 %09%09%7D%0A%0A%09%09return re
@@ -1737,16 +1737,115 @@
 ame());%0A
+%09%09StopWatch createWatch = new StopWatch(%22Measure time of method %22 + pjp.getSignature().getName());%0A
 %09%09create
@@ -2300,16 +2300,75 @@
 lis());%0A
+%09%09%09createTotalTime += createWatch.getLastTaskTimeMillis();%0A
 %09%09%7D%0A%0A%09%09r
@@ -2470,51 +2470,25 @@
 find
-Watch.getTotalTimeMillis(), createWatch.get
+TotalTime, create
 Tota
@@ -2488,29 +2488,21 @@
 ateTotalTime
-Millis()
 );%0A%09%7D%0A%0A%7D%0A

Make time measurement thread safe.