package de.tu_dresden.diplom.richter_mirko_mat2628335.witness.process;

import org.apache.log4j.Logger;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.data.IFHandlingInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.data.IFSignatureHandlingInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.*;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.comm.ContextCreationResponse;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.comm.IFContextCreationRequest;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.comm.IFContextCreationResponse;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.Constants;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.context.IFWitnessContextInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.context.WitnessContextManagerFactory;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.context.ex.ContextInfoInvalidException;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.context.ex.UnknownEntityException;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.evidence.WitnessEvidenceManagerFactory;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.evidence.BodyEvidence;

/**
 * 
 */
public class ContextCreationProcess implements IFProcess {

   private static final Logger logger = Logger.getLogger(ContextCreationProcess.class);

   private IFHandlingInfo requestHandlingInfo = null;
   private IFContextCreationRequest contextCreationRequest = null;

   private IFContextCreationResponse contextCreationResponse = null;
   private IFCoordinationContext headerResponse = null;

   public ContextCreationProcess(IFHandlingInfo requestHandlingInfo, IFContextCreationRequest contextCreationRequest) {
      this.requestHandlingInfo = requestHandlingInfo;
      this.contextCreationRequest = contextCreationRequest;
   }

   /**
    * The informations collected by the Axis-Handlers (who signed how, who encrypted how ...)
    *
    * @param requestHandlingInfo
    */
   public void setRequestHandlingInfo(IFHandlingInfo requestHandlingInfo) {
      this.requestHandlingInfo = requestHandlingInfo;
   }

   protected IFHandlingInfo getRequestHandlingInfo(){
      return requestHandlingInfo;
   }

   /**
    * The contextCreationRequest as has been transmitted by the requester within the SOAP-Body
    *
    * @param contextCreationRequest
    */
   public void setContextCreationRequest(IFContextCreationRequest contextCreationRequest) {
      this.contextCreationRequest = contextCreationRequest;
   }

   protected IFContextCreationRequest getContextCreationRequest(){
      return contextCreationRequest;
   }

   /**
    * The result of the create-prcoess that is beeing sent to the requester within the SOAP-Body.
    *
    * @return
    */
   public IFContextCreationResponse getContextCreationResponse() {
      return contextCreationResponse;
   }

   protected void setContextCreationResponse(IFContextCreationResponse resp){
      this.contextCreationResponse = resp;
   }

   /**
    * The Coordination-Context that is beeing sent back to the requester within the
    * SOAP-Header and indicates the context of all following operations initiated
    * by the requester.
    *
    * @return
    */
   public IFCoordinationContext getHeaderResponse() {
      return headerResponse;
   }

   protected void setHeaderResponse(IFCoordinationContext hdrResp){
      this.headerResponse = hdrResp;
   }

   public void perform() {
      final String fn = "[perform]";
      ContextCreationResponse contextCreationResponse = new ContextCreationResponse();
      setContextCreationResponse(contextCreationResponse);
      IFSignatureHandlingInfo bodyHandlingInfo = getRequestHandlingInfo().getSignatureHandlingInfoBody();
      if (bodyHandlingInfo.isSuccess()) {
         CoordinationContext headerResponse = new CoordinationContext();
         setHeaderResponse(headerResponse);
         headerResponse.setIdentification("diplom.compago.de/contextID/" + System.currentTimeMillis());
         headerResponse.setExpires("" + (System.currentTimeMillis() + getContextCreationRequest().getLifeTimeMS()));
         headerResponse.setRegistrationServiceAddress(Constants.SERVICE_ENDPOINT_WITNESS_DIGESTER);
         headerResponse.setAllowedSignatureAlgorithms(getContextCreationRequest().getAllowedSignatureAlgorithms());
         headerResponse.setDigestAlgorithm(getContextCreationRequest().getDigestAlgorithm());
         headerResponse.setCreationTime("" + System.currentTimeMillis());
         headerResponse.setTimeoutDigestAgreementOnRequestPhaseMS("" + getContextCreationRequest().getTimeoutMSRequest());
         headerResponse.setTimeoutDigestAgreementOnResponsePhaseMS("" + getContextCreationRequest().getTimeoutMSResponse());
         IFWitnessContextInfo witnessContextInfo = null;
         try {
            witnessContextInfo = WitnessContextManagerFactory.getContextManager().registerContext(headerResponse, getContextCreationRequest(), bodyHandlingInfo);
            contextCreationResponse.setNonce(getContextCreationRequest().getNonce());
            if (witnessContextInfo.isSuccessfulCreated()) {
               contextCreationResponse.setSuccess(true);
            } else {
               contextCreationResponse.setSuccess(false);
            }
            WitnessEvidenceManagerFactory.getEvidenceManager().registerSuccessfullCreatedContext(witnessContextInfo, new BodyEvidence(getRequestHandlingInfo()));
         } catch (UnknownEntityException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            contextCreationResponse.setSuccess(false);
         } catch (ContextInfoInvalidException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
         }
      } else {
         logger.error(fn + "");
         contextCreationResponse.setSuccess(false);
      }
   }

   public boolean isSuccess() {
      return getContextCreationResponse().isSuccess();
   }

}
