package org.eclipse.osee.ote.message;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.eclipse.osee.ote.core.environment.interfaces.ITestEnvironmentAccessor;
import org.eclipse.osee.ote.message.data.MessageData;

/**
 * This class will measure the time between sends.
  * <pre>
 * {@code
 * MessageSendPeriodTrace trace = new MessageSendPeriodTrace(TimeUnit.NANOSECONDS, testMessage, logger);
 * trace.start();
 * //wait or do stuff
 * trace.stop();
 * trace.printResults();
 * }
 * </pre>
 * @author Andrew M. Finkbeiner
 *
 */
public class MessageSendPeriodTrace extends MessageTimeTrace {
   
   public final String TRACE_TYPE = "MessageSendPeriodTrace";
   private SendTimer sendTimer;
   private int maxFlag = Integer.MAX_VALUE;
   private int minError = Integer.MIN_VALUE;
   private int maxError = Integer.MAX_VALUE;
   
   private MessageTraceOutput messageTraceOutput;
   private MessageTraceLogger messageTraceLogger;
   
   /**
    * @param environment - the test environment.
    * @param timeUnit - determines the resolution of the timing that is measured.
    * @param message - the message to measure
    * @param messageTraceLogger - logger to write output
    */
   @SuppressWarnings("rawtypes")
   public MessageSendPeriodTrace(ITestEnvironmentAccessor environment, TimeUnit timeUnit, Message message, MessageTraceLogger messageTraceLogger) {
      super(environment, message, timeUnit);
      sendTimer = new SendTimer(this);
      this.messageTraceOutput = new MessageTraceOutput();
      this.messageTraceLogger = messageTraceLogger;
   }
   
   /**
    * 
    * @param expected the expected period in the constructed TimeUnit
    * @param maxError the max variance off of the period in the constructed TimeUnit
    */
   public void setMaxVariance(int expected, int maxError){
      this.maxFlag = maxError;
      this.minError = expected - maxError;
      this.maxError = expected + maxError;
   }

   public void addStartEvent(String message){
      add(new TimeEvent(message));
   }

   @Override
   public void start(){
      super.start();
      getMessage().getDefaultMessageData().addSendListener(sendTimer);
   }
   
   @Override
   public void stop(){
      super.stop();
      getMessage().getDefaultMessageData().removeSendListener(sendTimer);
   }
   
   @Override
   public synchronized void printResults(){
      List<TimeEvent> events = get();
      int count = 0;
      int exceedanceCount = 0;
      double average = 0.0;
      double max = -1.0;
      double min = -1.0;
      
      SendEvent pre1 = null;
      SendEvent pre2 = null;
      for(TimeEvent event:events){
         if(event instanceof SendEvent){
            SendEvent sendEvent = (SendEvent)event;
            if(sendEvent.type == SendEventType.pre){
               pre1 = pre2;
               pre2 = sendEvent; 
            } 
         }
         if(pre1 != null && pre2 != null){
            long nanoDiff = pre2.getNanoTime() - pre1.getNanoTime();
            count++;
            long currentTime = getTimeUnit().convert(nanoDiff, TimeUnit.NANOSECONDS);
            
            if(currentTime >= 0){
               if(max < 0 || currentTime > max){
                  max = currentTime;
               }
               if(min < 0 || currentTime < min){
                  min = currentTime;
               }
               if(currentTime > maxError || currentTime < minError){
                  exceedanceCount++;
                  String maxMessage = String.format("%s: count[%d] %d [%d (count)] [%s]", getName(), count, currentTime, exceedanceCount, getTimeUnit().name());
                  System.out.println(maxMessage);
               }
               average = (((count-1) * average) + currentTime)/count;
            }
         }
      }
      messageTraceOutput.setMessage(getMessage().getMessageName());
      messageTraceOutput.setMessageRate(getMessageRate());
      messageTraceOutput.setTimeUnit(getTimeUnit().name());
      messageTraceOutput.setTraceType(TRACE_TYPE);
      messageTraceOutput.setCount(count);
      messageTraceOutput.setAverage(average);
      messageTraceOutput.setMin(min);
      messageTraceOutput.setMax(max);
      messageTraceOutput.setExceedanceCount(exceedanceCount);
      messageTraceOutput.setExceedanceThreshold(maxFlag);
      messageTraceOutput.setTestDurationSec(testDurationSec);
      if (messageTraceLogger != null){
         messageTraceLogger.logMessageTraceOutput(messageTraceOutput);
      }
   }
   
   private static class SendTimer implements IMessageSendListener {

      private MessageSendPeriodTrace messageSendOperator;

      public SendTimer(MessageSendPeriodTrace messageSendOperator) {
         this.messageSendOperator = messageSendOperator;
      }

      @Override
      public void onPreSend(MessageData messageData) {
         messageSendOperator.add(new SendEvent(SendEventType.pre));
      }

      @Override
      public void onPostSend(MessageData messageData) {
         // Intentionally empty block
      }
      
   }
   
   private static class SendEvent extends TimeEvent {
      
      public final SendEventType type;
      
      public SendEvent(SendEventType type) {
         super(type.name());
         this.type = type;
      }
      
   }
   
   private enum SendEventType {
      pre
   }
}
