package de.tu_dresden.diplom.richter_mirko_mat2628335.witness;

import org.apache.log4j.Logger;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.entity.IFEntity;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.entity.EntityManagerFactory;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.context.*;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.context.ex.ContextInfoInvalidException;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.account.IFAccount;
import de.tu_dresden.diplom.richter_mirko_mat2628335.witness.account.AccountPool;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.account.Amount;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.account.IFCurrency;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.*;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.context.comm.*;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.account.AccountIdentification;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.account.Amount;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.account.IFCurrency;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.Constants;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.entity.IFEntity;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.digestAgreement.DigestAgreementRequest;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.digestAgreement.IFDigestAgreementRequest;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.data.IFSignatureHandlingInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.data.SignatureHandlingInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.data.IFHandlingInfo;
import de.tu_dresden.diplom.richter_mirko_mat2628335.common.handler.data.HandlingInfo;

/**
 * 
 */
public class DTWitness {

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

   public static IFEntity getWitness() {
      return EntityManagerFactory.getEntityManager().locateEntityByAlias("Witness");
   }

   public static IFEntity getClient1() {
      return EntityManagerFactory.getEntityManager().locateEntityByAlias("Client1");
   }

   public static IFAccount getClient1Account(){
      return AccountPool.getAccount(getClient1(), new AccountIdentification("one"));
   }

   public static IFEntity getTicketReservation() {
      return EntityManagerFactory.getEntityManager().locateEntityByAlias("TicketReservation");
   }

   public static IFEntity getTicketBooking() {
      return EntityManagerFactory.getEntityManager().locateEntityByAlias("TicketBooking");
   }

   public static IFWitnessContextManager getContextManager() {
      return HLContextManager.getNewContextManager();
   }

   public static IFContextCreationRequest getContextCreationRequestOne(){
      return getContextCreationRequestOne(1000 * 60 * 20, 1000 * 30, 1000 * 30);
   }

   /**
    * Account: one<br/>
    * SigAlg: RSA-SHA1<br/>
    * Lifetime: 20min<br/>
    * RequestTimeout: 30s<br/>
    * ResponseTimeout: 30s<br/>
    * @return
    */
   public static IFContextCreationRequest getContextCreationRequestOne(long lifeTimeMS, long reqTimeout, long respTimeout) {
      ContextCreationRequest result = new ContextCreationRequest();
      result.setAccountIdentification(new AccountIdentification("one"));
      result.setAllowedSignatureAlgorithms(new String[]{Constants.NS_SIGNATURE_ALGORITHM_RSA_SHA1});
      result.setLifeTimeMS(lifeTimeMS);
      result.setNonce("ctxCreateReq1.nonce#1");
      result.setTimeoutMSRequest(reqTimeout);
      result.setTimeoutMSResponse(respTimeout);
      return result;
   }

   public static IFContextRemovalRequest getContextRemovalRequestOne(IFContextCreationResponse createResp){
      ContextRemovalRequest result = new ContextRemovalRequest();
      //result.
      return result;
   }

   public static IFCoordinationContext getCoordinationContextOne() {
      return getCoordinationContextOne(null);
   }

   public static IFCoordinationContext getCoordinationContextOne(IFContextCreationRequest req) {
      CoordinationContext result = new CoordinationContext();
      result.setCoordinationType("ACPUnitTestType#1");
      result.setCreationTime("" + System.currentTimeMillis());
      if (req != null) {
         result.setAllowedSignatureAlgorithms(req.getAllowedSignatureAlgorithms());
         result.setDigestAlgorithm(req.getDigestAlgorithm());
         result.setExpires("" + (System.currentTimeMillis() + req.getLifeTimeMS()));
      } else {
         result.setAllowedSignatureAlgorithms(new String[]{Constants.NS_SIGNATURE_ALGORITHM_RSA_SHA1});
         result.setDigestAlgorithm(Constants.NS_DIGEST_ALGORITHM_SHA1);
         result.setExpires("" + (System.currentTimeMillis() + 1000 * 60 * 20));
      }
      result.setIdentification("witnessCoordCtx/ident#1");
      result.setRegistrationServiceAddress("RegistrationAdress#1");
      return result;
   }

   public static IFHandlingInfo getHandlingInfoOne(IFContextCreationRequest req) {
      HandlingInfo handlingInfo1Temp = new HandlingInfo();
      CountingContext countingContext = new CountingContext();
      CoordinationContext coordCtx = new CoordinationContext();
      if (req != null) {
         coordCtx.setAllowedSignatureAlgorithms(req.getAllowedSignatureAlgorithms());
         coordCtx.setExpires("" + (System.currentTimeMillis() + req.getLifeTimeMS()));
      } else {
         coordCtx.setAllowedSignatureAlgorithms(new String[]{Constants.NS_SIGNATURE_ALGORITHM_RSA_SHA1});
         coordCtx.setExpires("" + (System.currentTimeMillis() + 1000 * 60 * 20));
      }
      coordCtx.setCoordinationType("ACPUnitTestType#1");
      coordCtx.setCreationTime("" + System.currentTimeMillis());
      coordCtx.setDigestAlgorithm(Constants.NS_DIGEST_ALGORITHM_SHA1);

      coordCtx.setIdentification("witnessCoordCtx/ident#1");
      coordCtx.setRegistrationServiceAddress("RegistrationAdress#1");
      countingContext.setCoordinationContext(coordCtx);
      handlingInfo1Temp.setCountingContext(countingContext);
      return handlingInfo1Temp;
   }

   /**
    *
    * @param req
    * @param respCtx
    * @return
    */
   public static IFHandlingInfo getHandlingInfoOne(IFContextCreationRequest req, IFCoordinationContext respCtx) {
      HandlingInfo handlingInfo1Temp = new HandlingInfo();
      CountingContext countingContext = new CountingContext();
      CoordinationContext coordCtx = new CoordinationContext();
      if (req != null) {
         coordCtx.setAllowedSignatureAlgorithms(req.getAllowedSignatureAlgorithms());
         coordCtx.setExpires("" + (System.currentTimeMillis() + req.getLifeTimeMS()));
      } else {
         coordCtx.setAllowedSignatureAlgorithms(new String[]{Constants.NS_SIGNATURE_ALGORITHM_RSA_SHA1});
         coordCtx.setExpires("" + (System.currentTimeMillis() + 1000 * 60 * 20));
      }
//      coordCtx.setAllowedSignatureAlgorithms();
      coordCtx.setCoordinationType(respCtx.getCoordinationType());
      coordCtx.setCreationTime(respCtx.getCreationTime());
      coordCtx.setDigestAlgorithm(respCtx.getDigestAlgorithm());

      coordCtx.setIdentification(respCtx.getIdentification());
      coordCtx.setRegistrationServiceAddress(respCtx.getRegistrationServiceAddress());
      countingContext.setCoordinationContext(coordCtx);
      handlingInfo1Temp.setCountingContext(countingContext);
      return handlingInfo1Temp;
   }

   public static IFSignatureHandlingInfo getCryptographicHandlingInfoOne() {
      return getCryptographicHandlingInfoOne(null);
   }

   public static IFSignatureHandlingInfo getCryptographicHandlingInfoOne(IFEntity actingEntity) {
      SignatureHandlingInfo result = new SignatureHandlingInfo();
      result.setResultCode(IFSignatureHandlingInfo.SUCCESS);
      if (actingEntity != null) {
         result.setActingEntity(actingEntity);
      } else {
         result.setActingEntity(DTWitness.getClient1());
      }
      return result;
   }

   public static IFDigestAgreementRequest getDigestAgreementRequestOne() {
      DigestAgreementRequest result = new DigestAgreementRequest();
      result.setContextID("witnessCoordCtx/ident#1");
      result.setDependency(null);
      result.setDigest("12345");
      result.setNonce("digAgreeReq1.nonce#1");
      result.setAccountIdentification(new AccountIdentification("default"));
      result.setAmount(new Amount(20, IFCurrency.CURRENCY_COUNTER_INST));
      return result;
   }

   public static DigestAgreementRequest getDigestAgreementRequest(IFCoordinationContext coordCtx){
      DigestAgreementRequest result = new DigestAgreementRequest();
      result.setContextID(coordCtx.getIdentification());
      result.setDependency(null);
      result.setDigest("12345");
      result.setNonce("digAgreeReq1.nonce#1");
      result.setAccountIdentification(new AccountIdentification("default"));
      result.setAmount(new Amount(20, IFCurrency.CURRENCY_COUNTER_INST));
      return result;
   }

   public static IFWitnessContextInfo getContextInfo(IFCoordinationContext coordCtx){
      WitnessContextInfo result = new WitnessContextInfo();
      try {
         result.setContextObject(coordCtx);
         result.setOwningEntity(getClient1());
         result.setSourceAccount(getClient1Account());
         result.setSuccessfullCreated(true);
      } catch (ContextInfoInvalidException e) {
         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
      }
      return result;
   }
}
