package de.tu_dresden.diplom.richter_mirko_mat2628335.services.context;

import org.apache.log4j.Logger;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.digestAgreement.IFDigestAgreementResponse;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.digestAgreement.IFDigestAgreementRequest;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.evidence.IFBodyEvidence;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.IFDigestAgreementStateInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.BaseContextManager;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.IFCountingContext;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.IFContextInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.data.IFHandlingInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.BaseHandler;

import java.util.Iterator;

/**
 * 
 */
public class ServiceContextManager extends BaseContextManager implements IFServiceContextManager{

   private static final Logger logger = Logger.getLogger(ServiceContextManager.class);
   public static final Logger contextStateMonitor = Logger.getLogger("monitor.state.context.service");

   protected ServiceContextManager() {
   }

   public Logger getInheritedLogger() {
      return logger;
   }

   public synchronized IFServiceContextInfo registerContext(IFCountingContext countingContext, IFHandlingInfo handlingInfo) {
      final String fn = "[registerContext] ";
      IFServiceContextInfo result = null;
      if(countingContext != null &&
           countingContext.getCoordinationContext() != null &&
           countingContext.getStepContext() != null &&
           countingContext.getIdentification() != null &&
           handlingInfo != null){
         IFContextInfo ctxInfo = getContext(countingContext.getIdentification());
         if(ctxInfo == null){
            if (logger.isDebugEnabled()) logger.debug(fn + "Creating new ServiceContextInfo for identififcation '" + countingContext.getIdentification() + "'");
            result = new ServiceContextInfo(countingContext);
            addContext(countingContext.getIdentification(), result);
            logRegisteredContextsToMonitor(fn);
         }else{
            if(ctxInfo instanceof IFServiceContextInfo){
               if (logger.isDebugEnabled()) logger.debug(fn + "The serviceContectInfo-object to context '" + countingContext.getIdentification() + "' already exists");
               result = (IFServiceContextInfo) ctxInfo;
               logRegisteredContextsToMonitor(fn);
            }else{
               logger.fatal(fn + "found ContextInfo-object of unknown type '" + ctxInfo.getClass().getName() + "'!");
            }
         }
      }else{
         StringBuffer err = new StringBuffer("CHECK FOR PARAMS FAILED: ");
         if (countingContext == null) {
            err.append("countingContext was NULL!");
         } else if (countingContext.getCoordinationContext() == null) {
            err.append("coordinationContext was NULL!");
         } else if (countingContext.getStepContext() == null) {
            err.append("stepContext was NULL!");
         } else if (countingContext.getIdentification() == null) {
            err.append("context identififcation was NULL");
         } else if(handlingInfo == null){
            err.append("handlingInfo was NULL!");
         }
         logger.error(fn + err);
      }
      return result;
   }

   private void logRegisteredContextsToMonitor(final String fn) {
      if (contextStateMonitor.isDebugEnabled()) {
         StringBuffer mon = new StringBuffer(fn);
         mon.append(getContextInfoObjectsCount()).append(" registered ServiceContextInfos").append("\n");
         int counter = 1;
         Iterator iterator = getContextInfoObjectsIterator();
         for (; iterator.hasNext();) {
            IFContextInfo info = (IFContextInfo) iterator.next();
            mon.append("\tServiceContextInfo_").append(counter).append(": \n");
            mon.append("\t\tIdentification: ").append(info.getIdentification()).append("\n");
            counter++;
         }
         contextStateMonitor.debug(mon);

      }
   }

   public synchronized boolean registerDigestAgreementStarted(String contextID, IFDigestAgreementRequest request, String communicationNonce) {
      final String fn = "[registerDigestAgreementStarted] ";
      boolean result = false;
      if(contextID != null && request != null){
         if(request.isRequestPhase()){
            registerCommunicationStarted(BaseHandler.getHandlingInfo().getCountingContext());
         }
      }else{
         StringBuffer err = new StringBuffer("CHECK FOR PARAMS FAILED: ");
         if (contextID == null) {
            err.append("contextID was NULL!");
         } else if (request == null) {
            err.append("digestAgreementRequest was NULL!");
         }
         logger.error(fn + err);
      }
      result = super.registerDigestAgreementStarted(contextID, request, communicationNonce);
      return result;
   }
}
