/*
 * The Cryptonit security software suite is developped by IDEALX
 * Cryptonit Team (http://IDEALX.org/ and http://cryptonit.org).
 *
 * Copyright 2003-2006 IDEALX
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301, USA. 
 *
 * In addition, as two special exceptions:
 *
 * 1) IDEALX S.A.S gives permission to:
 *  * link the code of portions of his program with the OpenSSL library under
 *    certain conditions described in each source file
 *  * distribute linked combinations including the two, with respect to the
 *    OpenSSL license and with the GPL
 *
 * You must obey the GNU General Public License in all respects for all of the
 * code used other than OpenSSL. If you modify file(s) with this exception,
 * you may extend this exception to your version of the file(s), but you are
 * not obligated to do so. If you do not wish to do so, delete this exception
 * statement from your version, in all files (this very one along with all
 * source files).

 * 2) IDEALX S.A.S acknowledges that portions of his sourcecode uses (by the
 * way of headers inclusion) some work published by 'RSA Security Inc.'. Those
 * portions are "derived from the RSA Security Inc. PKCS #11Cryptographic
 * Token Interface (Cryptoki)" as described in each individual source file.
 */

#ifndef _DN_H__
#define _DN_H__

#include <list>
#include <vector>
#include <string>
#include <iostream>

#include "OpenSSL++.hh"

#define DN_DISPLAY_LONG  0x0001
#define DN_DISPLAY_SHORT 0x0002
#define DN_DISPLAY_VALUE 0x0004



namespace Cryptonit{


    /**
     * Classe rdn représentant une entrée d'un Distinguish Name
     * @see dn
     **/
  
    class rdn {
    private:
	/**
	 * Pointeur vers une entrée d'un dn d'OpenSSL
	 * */
	X509_NAME_ENTRY *ne;
    public:
	/**
	 * Constructeur par défaut.
	 * initialise ne à NULL.
	 * @see ne
	 * */
	rdn ();
	/**
	 * Constructeur de copie.
	 * */
	rdn (const rdn &n);
	/**
	 * Constructeur à partir d'une entrée d'OpenSSL
	 * @param n est dupliquée.
	 * */
	rdn (X509_NAME_ENTRY *n);
	/**
	 * Destructeur
	 * */
	~rdn();
	/**
	 * libère la mémoire occupée par ne
	 * @see ne
	 * */
	void free();

	/**
	 * renvoie le nom abbrégé de l'entrée
	 * */
	std::string getShortName() const;
	/**
	 * renvoie le nom complet de l'entrée
	 * */
	std::string getLongName() const;
	/**
	 * renvoie l'identifiant de l'entrée
	 * */
	std::string getOID() const;
	/**
	 * renvoie la vleur de l'entrée
	 * */
	std::string getValue () const;
	/**
	 * renvoie une entrée sous forme de texte
	 * */
	std::string getInfos() const;


	std::string getInfosList() const;

	/**
	 * surcharge de <<
	 * */
	friend std::ostream& operator<< (std::ostream& cout, rdn &r);
    };

    /**
     * Classe representant les Distinguish Names
     *
     * @doc Classe dn représentant un DN
     **/

    class dn {
    private:
	/**
	 * std::liste des entrées du DN
	 * @see rdn
	 * */
	std::list<rdn> rdns;

	/**
	 * Pointeur vers le dn d'openssl
	 * */
	X509_NAME *name;

    public:

	/**
	 * Constructeur par défaut
	 * */
	dn ();
	/**
	 * Constructeur de copie
	 * */
	dn (const dn &d);
	/**
	 * Constructeur à partir d'un DN d'OpenSSL
	 * @param n est dupliqué.
	 * */
	dn (X509_NAME *n);
	/**
	 * Destructeur
	 * */
	~dn();

	/**
	 * Libère la mémoire occupée par rdns
	 * @see rdns
	 * */
	void free();

	/**
	 * renvoie la std::liste des entrées du DN
	 * @see rdn
	 * */
	const std::list<rdn> &getDN();

	/**
	 * renvoie un DN sous forme de texte
	 * */
	std::string getInfos() const;

	/**
	 * renvoie un label à partir des entrée du DN.
	 * Cette fonction est utilsée par x509Book pour obtenir un nom à une entrée.
	 * @see x509Book
	 * */
	std::string label();

	/**
	 * renvoie la valeur de l'entrée du DN dont les initiales sont shortName.
	 * */
	std::string getValue(const std::string &shortName);
    
    
	/**
	 * display the values of the Dn, each field will be separated by the "separator" char.
	 * sub will replace non displayable characters.
	 **/
	std::string getValues(int mask= DN_DISPLAY_LONG | DN_DISPLAY_VALUE, char separator='\n'
			      , char sub='.');
	
	/** get a vector with the values of this Dn 
	 * @param mask : describes the values to get.
	 * @param separator : a string which is inserted between the value name and the value
	 * @return a vector of std::string
	 */
	const std::vector<std::string> getValuesVect(int mask = DN_DISPLAY_LONG | DN_DISPLAY_VALUE, 
						     std::string separator = ": " );
      
	/* get a vector of infos about the distinguish name*/
	const std::vector<std::string> getInfosList() const;
      
	const std::vector<std::string> getInfosList(std::vector<std::string> infoList)  const;
      
    
	
	X509_NAME *getX509Name();

	bool compare(dn &dnb);
    
	/**
	 * surcharge de <<
	 * */
	friend std::ostream& operator<< (std::ostream& cout, dn& d);
    };

}
#endif
