package de.tu_dresden.diplom.richter_mirko_mat2628335.uddipopulation;

import org.apache.log4j.Logger;

import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;

/**
 * Entry-Description for one specific UDDI-Entry (accessPoint, certificate) to be communicated
 * to the prototype "usage counter fpr ws-access"
 */
public class UDDIBindingCertEntry {

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

   private String accessPoint = null;

   private X509Certificate[] certificatesInUDDI = null;

   /**
    * Gets the Certificates that have been obtained from the UDDI-Registry.
    * @return The certificates
    */
   public X509Certificate[] getCertificatesInUDDI() {
      return certificatesInUDDI;
   }

   /**
    * Sets the Certificates that have been obtained from the UDDI-Registry.
    */
   public void setCertificatesInUDDI(X509Certificate[] certificatesInUDDI) {
      this.certificatesInUDDI = certificatesInUDDI;
   }

   /**
    * Gets the Access-Point (URL-style) for this entry that was red
    * out of the UDDI-registry
    * @return The accessPoint.
    */
   public String getAccessPoint() {
      return accessPoint;
   }

   /**
    * Sets the Access-Point of this entry
    * @param accessPoint The new Access-Point
    */
   public void setAccessPoint(String accessPoint) {
      this.accessPoint = accessPoint;
   }

   /**
    * Gest the last Certificate in the chain that is for the prototype
    * assumed to be the certificate of the service (also assumed that exactly two certificates are
    * in UDDI-entry).
    * @return The last certificate of the chain (assumed to be the one of the service)
    */
   public X509Certificate getLastCertificate(){
      final String fn = "[getLastCertificate] ";
      X509Certificate result = null;
      if(certificatesInUDDI == null || certificatesInUDDI.length != 2){
         logger.error(fn + "prototype-assumption for number of certificates in UDDI broken!");
      }else{
         X509Certificate first = certificatesInUDDI[0];
         X509Certificate second = certificatesInUDDI[1];
         boolean hierarchyFound = false;
         try {
            first.verify(second.getPublicKey());
            result = first;
            hierarchyFound = true;
            if (logger.isDebugEnabled()) logger.debug(fn + "The first found to be signed by the second!");
         } catch (CertificateException e) {
            //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
         } catch (NoSuchAlgorithmException e) {
            //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
         } catch (InvalidKeyException e) {
            //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
         } catch (NoSuchProviderException e) {
            //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
         } catch (SignatureException e) {
            //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            result = second;
         }
         if(!hierarchyFound){
            try {
               second.verify(first.getPublicKey());
               result = second;
               hierarchyFound = true;
               if (logger.isDebugEnabled()) logger.debug(fn + "The second found to be signed by the first!");
            } catch (CertificateException e) {
               //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            } catch (NoSuchAlgorithmException e) {
               //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            } catch (InvalidKeyException e) {
               //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            } catch (NoSuchProviderException e) {
               //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            } catch (SignatureException e) {
               //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
         }
         if(!hierarchyFound){
            logger.fatal(fn + "No hierarchy could be determined within the given chains");
         }
      }
      return result;
   }

}
