/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
 * XSEC
 *
 * DSIG_Reference := Class for checking and setting up reference nodes in a DSIG signature
 *
 * $Id$
 *					 
 */

#ifndef DSIGREFERENCE_INCLUDE
#define DSIGREFERENCE_INCLUDE

// High level include
#include <xsec/framework/XSECDefs.hpp>

// Xerces INcludes

#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMNamedNodeMap.hpp>

// XSEC Includes
#include <xsec/utils/XSECSafeBufferFormatter.hpp>
#include <xsec/dsig/DSIGTransform.hpp>
#include <xsec/dsig/DSIGReferenceList.hpp>
#include <xsec/dsig/DSIGConstants.hpp>

class DSIGTransformList;
class DSIGTransformBase64;
class DSIGTransformC14n;
class DSIGTransformEnvelope;
class DSIGTransformXPath;
class DSIGTransformXPathFilter;
class DSIGTransformXSL;
class DSIGSignature;
class DSIGSignedInfo;

class TXFMBase;
class TXFMChain;
class XSECBinTXFMInputStream;
class XSECURIResolver;
class XSECEnv;

/**
 * @ingroup pubsig
 */

/**
 * @brief The class used for manipulating Reference Elements within a signature.
 *
 * <p>The DSIGReference class creates and manipulates (including hashing and validating)
 * \<Reference\> elements.</p>
 *
 */

class XSEC_EXPORT DSIGReference {

public:

    /** @name Constructors and Destructors */
    //@{
	
    /**
	 * \brief Contructor for use with existing XML signatures or templates.
	 *
	 * <p>Create a DSIGReference object based on an already existing
	 * DSIG Reference XML node.  It is assumed that the underlying
	 * DOM structure is in place and works correctly.</p>
	 *
	 * @note DSIGReference structures should only ever be created via calls to a
	 * DSIGSignature object.
	 *
	 * @param env The operating environment in which the Reference is operating
	 * @param dom The DOM node (within doc) that is to be used as the base of the reference.
	 * @see #load
	 * @see DSIGSignature#createReference
	 */

	DSIGReference(const XSECEnv * env, XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *dom);

    /**
	 * \brief Contructor for use when creating new Reference structures.
	 *
	 * <p>Create a DSIGReference object that can later be used to create
	 * a new Reference structure in the DOM document.</p>
	 *
	 * @note DSIGReference structures should only ever be created via calls to a
	 * DSIGSignature object.
	 *
	 * @param env The environment object for this reference.
	 * @see #load
	 * @see DSIGSignature#createReference
	 */
	
	DSIGReference(const XSECEnv * env);

	/**
	 * \brief Destructor.
	 *
	 * @note Does not impact any created DOM structures when destroyed.
	 *
	 * @note DSIGReferences should <em>never</em> be destroyed/deleted by
	 * applications.  They are owned and managed by DSIGSignature structures.
	 */

	~DSIGReference();

	//@}

    /** @name Reference Construction and Manipulation */
    //@{

	/**
	 * \brief Load a DSIGReference from an existing DOM structure.
	 *
	 * <p>This function will load a Reference structure from the owner
	 * document.</p>
	 *
	 */
	
	void load();

	/**
	 * \brief Create a Reference structure in the document.
	 *
	 * <p>This function will create a Reference structure in the owner
	 * document.  In some cases, a call to this function will be sufficient
	 * to put the required Reference in place.  In other cases, calls will
	 * also need to be made to the various append*Transform methods.</p>
	 *
	 * @note The XSEC Library currently makes very little use of <em>type</em>
	 * attributes in \<Reference\> Elements.  However this may of use to calling
	 * applications.
	 *
	 * @param URI The URI (data source) for this reference.  Set to NULL for
	 * an anonymous reference.
	 * @param hashAlgorithmURI The type of Digest to be used (generally SHA-1)
	 * @param type A type string (as defined by XML Signature).
	 * @returns The root Reference element of the newly created DOM structure.
	 */

	XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * 
		createBlankReference(const XMLCh * URI, 
			const XMLCh * hashAlgorithmURI, 
			const XMLCh * type);

	/**
	 * \brief Append an Enveloped Signature Transform to the Reference.
	 *
	 * Appends a simple enveloped-signature transform to the list of transforms
	 * in this element.
	 *
	 * @returns The newly created envelope transform.
	 *
	 */

	DSIGTransformEnvelope *  appendEnvelopedSignatureTransform();
	
	/**
	 * \brief Append a Base64 Transform to the Reference.
	 *
	 * @returns The newly created Base64 transform.
	 */

	DSIGTransformBase64 * appendBase64Transform();
	
	/**
	 * \brief Append an XPath Transform to the Reference.
	 *
	 * <p> Append an XPath transform.  Namespaces can be added to the 
	 * transform directly using the returned <em>DSIGTransformXPath</em>
	 * structure</p>
	 *
	 * @param expr The XPath expression to be placed in the transform.
	 * @returns The newly created XPath transform
	 */

	DSIGTransformXPath * appendXPathTransform(const char * expr);
	
	/**
	 * \brief Append an XPath-Filter2 Transform to the Reference.
	 *
	 * The returned DSIGTransformXPathFilter will have no actual filter
	 * expressions loaded, but calls can be made to
	 * DSIGTransformXPathFilter::appendTransform to add them.
	 *
	 * @returns The newly created XPath Filter transform
	 */

	DSIGTransformXPathFilter * appendXPathFilterTransform(void);

	/**
	 * \brief Append an XSLT Transform to the Reference.
	 *
	 * <p>The caller must have already create the stylesheet and turned it into
	 * a DOM structure that is passed in as the stylesheet parameter.</p>
	 *
	 * @param stylesheet The stylesheet DOM structure to be placed in the reference.
	 * @returns The newly create XSLT transform
	 */

	DSIGTransformXSL * appendXSLTransform(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *stylesheet);
	
	/**
	 * \brief Append a Canonicalization Transform to the Reference.
	 *
	 * @param canonicalizationAlgorithmURI The type of canonicalisation to be added.
	 * @returns The newly create canonicalisation transform
	 */

	DSIGTransformC14n * appendCanonicalizationTransform(
		const XMLCh * canonicalizationAlgorithmURI
	);

	/**
	 * \brief Append a "debug" transformer.
	 *
	 * This method allows applications to provide a TXFM that will be appended
	 * to the transform chain just prior to the application of the hash
	 * algorithm.
	 *
	 * @note This is primarily for debugging.  It should not be used to modify the
	 * contents of the byte stream.
	 *
	 * @param t The TXFM element to insert.
	 */
	
	void setPreHashTXFM(TXFMBase * t);

   /**
    * \brief Set the Id attribute of the DSIGReference
    *
    * This method allows applications to set the Id attribute of the DSIGReference
    * as described in http://www.w3.org/TR/xmldsig-core/#sec-Reference.
    *
    *
    * @param id The value for this reference.
    */
   void setId(const XMLCh *id);

   /**
    * \brief Set the Type attribute of the DSIGReference
    *
    * This method allows applications to set the Type attribute of the DSIGReference
    * as described in http://www.w3.org/TR/xmldsig-core/#sec-Reference.
    *
    *
    * @param type The value for this reference.
    */
   void setType(const XMLCh *type);
	//@}

	/** @name Getting Information */
	//@{

	/**
	 * \brief Create an input stream based on the digested byte stream.
	 *
	 * This method allows applications to read the fully canonicalised
	 * byte stream that is hashed for a reference.
	 *
	 * All transforms are performed up to the point where they would
	 * normally be fed into the Digest function.
	 *
	 * @returns A BinInputSource of the canonicalised SignedInfo
	 */

	XSECBinTXFMInputStream * makeBinInputStream(void) const;

	/**
	 * \brief Return the URI string of the Reference.
	 *
	 * @returns A pointer to the buffer (owned by the Reference) containing 
	 * the value of the URI stored inthe reference
	 */

	const XMLCh * getURI() const;

    /**
     * \brief Get the Digest Algorithm URI
     *
     * @returns the URI associated with the Algorithm used to generate
     * the digest
     */

    const XMLCh * getAlgorithmURI() const {
        return mp_algorithmURI;
    }

	/**
	 * \brief Obtain the transforms for this reference
	 *
	 * Get the DSIGTransformList object for this reference.  Can be used to
	 * obtain information about the transforms and also change the the transforms
	 */

	DSIGTransformList * getTransforms(void) const {
		return mp_transformList;
	}

	/**
	 * \brief Determine whether the reference is a manifest
	 *
	 * @returns true iff the Reference element is a Manifest reference
	 */
	
	bool isManifest() const;

	/**
	 * \brief Get the Manifest
	 *
	 * @returns The ReferenceList containing the references in the Manifest
	 * list of this reference element.
	 */

	DSIGReferenceList * getManifestReferenceList() const;		// Return list of references for a manifest object


	//@}
	
	/** @name Message Digest/Hash manipulation */
	//@{

	/**
	 * \brief Calculate the Hash  value of a reference
	 *
	 * Takes the Reference URI, performs all the transforms and finally
	 * calculates the Hash value of the data using the Digest algorithm
	 * indicated in the reference
	 *
	 * @param toFill A Buffer that the raw hash will be copied into.
	 * @param maxToFill Maximum number of bytes to place in the buffer
	 * @returns The number of bytes copied into the buffer
	 */

	unsigned int calculateHash(XMLByte * toFill, unsigned int maxToFill) const;

	/**
	 * \brief Read the hash from the Reference element.
	 *
	 * Reads the Base64 encoded element from the Reference element.
	 * The hash is then translated from Base64 back into raw form and
	 * written into the indicated buffer.
	 *
	 * @param toFill Pointer to the buffer where the raw hash will be written
	 * @param maxToFill Maximum bytes to write to the buffer
	 * @returns Number of bytes written
	 */
	
	unsigned int readHash(XMLByte *toFill, unsigned int maxToFill) const;

	/**
	 * \brief Validate the Reference element
	 *
	 * Performs a #calculateHash() and a #readHash() and then compares the
	 * results.
	 *
	 * @returns true iff the hash of the data matches the hash stored 
	 * in the reference.
	 */

	bool checkHash() const;

	/**
	 * \brief Set the value of the hash in the Reference
	 *
	 * Hashes the data referenced by the element and then writes
	 * the Base64 encoded hash value into the Reference.
	 *
	 */

	void setHash();

	//@}

	/** @name Helper (static) Functions */	
	//@{

	/**
	 * \brief Create a Transformer chain
	 *
	 * Given a TransformList create the corresponding TXFM chain to allow
	 * the caller to read the reference byte stream
	 *
	 * @note This method is primarily for use within the XSEC library.
	 * Users wishing to get the byte stream should use the #makeBinInputStream
	 * method instead.
	 *
	 * @param input The input transformer to which the TXFMs will be applied to
	 * This is generally created from the URI attribute of the reference.
	 * @param lst The list of Transform elements from which to build the 
	 * transformer list.
	 * @returns The <B>end</B> of the newly build TXFM chain.  This can be 
	 * read from using TXFMBase::readBytes() to give the end result of the
	 * transforms.
	 */

	static TXFMChain * createTXFMChainFromList(TXFMBase * input, 
							DSIGTransformList * lst);

	/**
	 * \brief Load a Transforms list from the \<Transforms\> DOMNode.
	 *
	 * Reads the data from the XML data stored in the DOM and create
	 * the associated DSIGTrasnformList.
	 *
	 * @param transformsNode Starting node in the DOM
	 * @param formatter The formatter to be used to move from XMLCh to strings
	 * @param env Environment in which to operate
	 * @returns A pointer to the created list.
	 */

	static DSIGTransformList * loadTransforms(
							XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *transformsNode,
							XSECSafeBufferFormatter * formatter,
							const XSECEnv * env);

	/**
	 * \brief Create a starting point for a TXFM Chain.
	 *
	 * Uses the provided URI to find the base data that the Transformer chain
	 * will be built upon.
	 *
	 * @param doc The document that the signature is based on (used for local URIs)
	 * @param URI The URI to build the base from
	 * @param env The environment the signature is operating in
	 * @returns A base TXFM element.
	 */

	static TXFMBase * getURIBaseTXFM(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * doc, 
									const XMLCh * URI, 
									const XSECEnv * env);

	/**
	 * \brief Load a series of references.
	 *
	 * Takes a series of \<Reference\> elements in a DOM structure
	 * and creates the corresponding ReferenceList object.
	 *
	 * @note Internal function - meant for use by the library
	 *
	 * @param env The environment in which this reference resides
	 * @param firstReference First reference in DOM structure
	 * @returns the created list.
	 */

	static DSIGReferenceList *loadReferenceListFromXML(const XSECEnv * env, 
													   XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *firstReference);

	/**
	 * \brief Validate a list of references.
	 *
	 * Runs through a reference list, calling verify() on each and 
	 * setting the ErrroStrings for any errors found
	 *
	 * @param lst The list to verify
	 * @param errorStr The string to append any errors found to
	 * @returns true iff all the references validate successfully.
	 */

	static bool verifyReferenceList(const DSIGReferenceList * lst, safeBuffer &errorStr);
	
	/**
	 * \brief Hash a reference list
	 * 
	 * Run through a list of references and calculate the hash value of each
	 * element.  Finally set the Base64 encoded string according to the newly
	 * calcuated hash.
	 *
	 * @note This is an internal library function and should not be called directly.
	 *
	 * @param list The list of references
	 * @param interlocking If set to false, the library will assume there
	 * are no inter-related references.  The algorithm for determining this
	 * internally is very primitive and CPU intensive, so this is a method to 
	 * bypass the checks.
	 */
	static void hashReferenceList(const DSIGReferenceList * list, bool interlocking = true);

	//@}

private:

	// Internal functions
	void createTransformList(void);
	void addTransform(
		DSIGTransform * txfm, 
		XERCES_CPP_NAMESPACE_QUALIFIER DOMElement * txfmElt
	);


	XSECSafeBufferFormatter		* mp_formatter;
	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode						
								* mp_referenceNode;		// Points to start of document where reference node is
	mutable TXFMBase				* mp_preHash;			// To be used pre-hash
	DSIGReferenceList			* mp_manifestList;		// The list of references in a manifest
	const XMLCh					* mp_URI;				// The URI String
	bool						m_isManifest;			// Does this reference a manifest?
	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode						
								* mp_transformsNode;
	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode						
								* mp_hashValueNode;		// Node where the Hash value is stored
	const XSECEnv				* mp_env;
	DSIGTransformList			* mp_transformList;		// List of transforms
	const XMLCh					* mp_algorithmURI;		// Hash algorithm for this reference
	
	bool                        m_loaded;

	DSIGReference();

	/*\@}*/

	friend class DSIGSignedInfo;
};

#endif /* #define DSIGREFERENCE_INCLUDE */
