package at.gv.egovernment.moa.spss.server.config;

import java.math.BigInteger;
import java.security.Principal;

import iaik.asn1.structures.Name;
import iaik.utils.RFC2253NameParser;
import iaik.utils.RFC2253NameParserException;

/**
 * A class containing the issuer and serial number of a certificate, which can
 * be used to uniquely identify the certificate.
 * 
 * The issuer is contained as an RFC2253 encoded <code>String</code>.
 * 
 * @author Patrick Peck
 * @version $Id$
 */
public class IssuerAndSerial {

  /** The issuer distinguished name. */
  private String issuerDN;
  /** The certificate serial number. */
  private BigInteger serial;

  /**
   * Create an <code>IssuerAndSerial</code> object.
   * 
   * The name of the issuer is converted to RFC2253. If it cannot be parsed, the
   * DN contained in the <code>issuer</code> is set. 
   * 
   * @param issuer The isser of a certificate.
   * @param serial The serial number of the certificate.
   */
  public IssuerAndSerial(Principal issuer, BigInteger serial) {
    RFC2253NameParser parser = new RFC2253NameParser(issuer.getName());

    try {
      this.issuerDN = ((Name) parser.parse()).getRFC2253String();
    } catch (RFC2253NameParserException e) {
      this.issuerDN = issuer.getName();
    }
    this.serial = serial;
  }
  
  /**
   * Create an <code>IssuerAndSerial</code> object.
   * 
   * @param issuerDN The issuer distinguished name. Should be an RFC2253 name.
   * @param serial The serial number of the certificate.
   */
  public IssuerAndSerial(String issuerDN, BigInteger serial) {
    this.issuerDN = issuerDN;
    this.serial = serial;
  }

  /**
   * Return the issuer DN in RFC2253 format.
   * 
   * @return The issuer part of this object.
   */
  public String getIssuerDN() {
    return issuerDN;
  }

  /**
   * Return the serial number.
   * 
   * @return The serial number of this object.
   */
  public BigInteger getSerial() {
    return serial;
  }

  /**
   * Compare this <code>IssuerAndSerial</code> to another object.
   * 
   * @param other The object to compare this <code>IssuerAndSerial</code> to.
   * @return <code>true</code>, if <code>other</code> is an
   * <code>IssuerAndSerial</code> object and the <code>issuer</code> and
   * <code>serial</code> fields are both equal. <code>false</code> otherwise.
   * @see java.lang.Object#equals(java.lang.Object)
   */
  public boolean equals(Object other) {
    if (other instanceof IssuerAndSerial) {
      IssuerAndSerial ias = (IssuerAndSerial) other;
      return getIssuerDN().equals(ias.getIssuerDN())
        && getSerial().equals(ias.getSerial());
    }
    return false;
  }

  /**
   * Return the hash code of this <code>IssuerAndSerial</code>.
   * 
   * @return The hash code of this <code>IssuerAndSerial</code>.
   * @see java.lang.Object#hashCode()
   */
  public int hashCode() {
    return issuerDN.hashCode() ^ serial.hashCode();
  }

  /**
   * Return a <code>String</code> representation of this
   * <code>IssuerAndSerial</code> object.
   * 
   * @return The <code>String</code> representation.
   * @see java.lang.Object#toString()
   */
  public String toString() {
    return ("(IssuerAndSerial - Issuer<" + getIssuerDN())
      + ("> Serial<" + serial.toString() + ">)");
  }

}