/**
 * 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
 *
 * txfmout:= tool to output the results of the various transforms
 *		     used when validating the attached signature.
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

// XSEC

#include <xsec/utils/XSECPlatformUtils.hpp>
#include <xsec/framework/XSECProvider.hpp>
#include <xsec/canon/XSECC14n20010315.hpp>
#include <xsec/dsig/DSIGSignature.hpp>
#include <xsec/dsig/DSIGReference.hpp>
#include <xsec/framework/XSECException.hpp>
#include <xsec/framework/XSECURIResolver.hpp>
#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/utils/XSECBinTXFMInputStream.hpp>

#include "../../utils/XSECDOMUtils.hpp"

// General

#include <memory.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <stdlib.h>

#if defined(HAVE_UNISTD_H)
# include <unistd.h>
#else
# if defined(HAVE_DIRECT_H)
#  include <direct.h>
# endif
#endif


#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLException.hpp>
#include <xercesc/util/XMLNetAccessor.hpp>
#include <xercesc/util/XMLUri.hpp>

XERCES_CPP_NAMESPACE_USE

using std::ios;
using std::cout;
using std::cerr;
using std::endl;
using std::ofstream;

#ifdef XSEC_HAVE_XALAN

// XALAN

#include <xalanc/XPath/XPathEvaluator.hpp>
#include <xalanc/XalanTransformer/XalanTransformer.hpp>

// If this isn't defined, we're on Xalan 1.12+ and require modern C++
#ifndef XALAN_USING_XALAN
# define XALAN_USING_XALAN(NAME) using xalanc :: NAME;
#endif

XALAN_USING_XALAN(XPathEvaluator)
XALAN_USING_XALAN(XalanTransformer)

#else

std::ostream& operator<< (std::ostream& target, const XMLCh * s)
{
    char *p = XMLString::transcode(s);
    target << p;
    XSEC_RELEASE_XMLCH(p);
    return target;
}

#endif

// ---------------------------------------------------------------------------
//  Outputter
// ---------------------------------------------------------------------------

class outputter {

public:

	outputter();
	~outputter();

	// Set methods

	// Will tell not to use cout and open on this base
	void setFilename(const char * name);
	// Will append a number and re-open for each "open" call
	void setNewFilePerOpen();

	// Re-open the file if necessary (new output)
	void openSection();
	// Close if necessary (output section finished)
	void closeSection();
	// Close of and finish
	void closeAll();

	// Output a buffer
	void output(const unsigned char * buf, unsigned int sz);

	// Info
	int getIndex(void);

private:

	char			* m_name;			// Name of the file (or base name)
	bool			m_cout;				// Are we using cout?
	bool			m_newFilePerOpen;	// Should we re-open?
	bool			m_fileOpen;			// Do we have an open file we should close?
	int				m_counter;			// The counter
	ofstream		m_out;				// Current output file

};

outputter::outputter() :
m_name(0),
m_cout(true),
m_newFilePerOpen(false),
m_fileOpen(false),
m_counter(0) {

}

outputter::~outputter() {

	if (m_fileOpen == true) {

		m_out.close();

		m_fileOpen = false;

	}

	if (m_name != 0)
		delete[] m_name;

}

void outputter::setFilename(const char * name) {

	m_name = strdup(name);
	m_cout = false;

}

void outputter::setNewFilePerOpen() {

	m_newFilePerOpen = true;

}

void outputter::openSection() {

	if (m_cout == true)
		return;

	if (m_fileOpen == true && m_newFilePerOpen == false)
		return;

	if (m_out.is_open() != 0) {

		m_out.close();

	}

	char * buf = new char[strlen(m_name) + 10];
	strcpy(buf, m_name);

	if (m_newFilePerOpen == true) {

		char numBuf[10];
		sprintf(numBuf, "%d", m_counter);
		//_itoa(m_counter, numBuf, 10);
		strcat(buf, ".");
		strcat(buf, numBuf);

	}

	m_out.open(buf, ios::out | ios::binary);
	m_fileOpen = true;
	delete [] buf;
}

void outputter::closeSection() {

	m_counter++;

	if (m_cout == false && m_newFilePerOpen == true && m_out.is_open() != 0) {

		m_out.close();
		m_fileOpen = false;

	}


}

int outputter::getIndex(void) {

	return m_counter;

}

void outputter::closeAll() {

	if (m_out.is_open() != 0)
		m_out.close();

	m_fileOpen = false;

}


void outputter::output(const unsigned char * buf, unsigned int sz) {

	if (m_cout || m_out.is_open() == false) {

		cout.write((const char *) buf,sz);

	}
	else {

		m_out.write((const char *) buf, sz);

	}

}


// ---------------------------------------------------------------------------
//  Main Program
// ---------------------------------------------------------------------------



void printUsage(void) {

	cerr << "\nUsage: txfmout [options] <input file name>\n\n";
	cerr << "     Where options are :\n\n";
	cerr << "     --signedinfo/-s\n";
	cerr << "         Output canonicalised SignedInfo only\n";
	cerr << "     --out/-o\n";
	cerr << "         Output to the nominated file name\n";
	cerr << "     --references/-r [num]\n";
	cerr << "         Output only references. [num] defines a single reference to output\n";
	cerr << "     --newfiles/-n\n";
	cerr << "         Create a new file for each reference/SignedInfo (append .#)\n";

}

// ---------------------------------------------------------------------------
//		Reference Outputter
// ---------------------------------------------------------------------------

void outputReferenceList (DSIGReferenceList * lst, outputter & theOutputter, int refNum) {

	if (lst == 0)
		return;
	
	DSIGReference * ref;
	unsigned int sz;
	XSECBinTXFMInputStream * is;
	unsigned char buf[1024];

    DSIGReferenceList::size_type lstSz = (int) lst->getSize();

	for (DSIGReferenceList::size_type i = 0; i < lstSz; ++i) {

		ref = lst->item(i);
		if (refNum == -1 || theOutputter.getIndex() == refNum) {
			theOutputter.openSection();
	
			try {
				is = ref->makeBinInputStream();
			}
			catch (const NetAccessorException&) {

				cerr << "Network error in reference " << theOutputter.getIndex() << endl;
				is = 0;
			}


			if (is != 0) {

				sz = (unsigned int) is->readBytes(buf, 1023);

				while (sz != 0) {
					
					buf[sz] = '\0';
					theOutputter.output(buf, sz);

					sz = (unsigned int) is->readBytes(buf, 1023);

				}

				delete is;

			}
		}
		theOutputter.closeSection();

	}

	// Look for manifests
	for (DSIGReferenceList::size_type i = 0; i < lstSz; ++i) {

		ref = lst->item(i);

		if (ref->isManifest() == true) {
			outputReferenceList(ref->getManifestReferenceList(), theOutputter, refNum);
		}

	}

}

// ---------------------------------------------------------------------------
//  Main Program
// ---------------------------------------------------------------------------


int main(int argc, char **argv) {

	char					* filename = NULL;
	bool					signedInfo = true;
	bool					references = true;
	outputter				theOutputter;
	int						refNum = -1;

	if (argc < 2) {

		printUsage();
		exit (2);
	}

	// Run through parameters
	int paramCount = 1;

	while (paramCount < argc - 1) {

		if (_stricmp(argv[paramCount], "--signedinfo") == 0 || _stricmp(argv[paramCount], "-s") == 0) {
			paramCount++;
			references = false;
		}
		else if (_stricmp(argv[paramCount], "--out") == 0 || _stricmp(argv[paramCount], "-o") == 0) {
			paramCount++;
			theOutputter.setFilename(argv[paramCount++]);
		}
		else if (_stricmp(argv[paramCount], "--references") == 0 || _stricmp(argv[paramCount], "-r") == 0) {
			paramCount++;
			signedInfo = false;
			if (argv[paramCount][0] >= '0' && argv[paramCount][0] <= '9')
				refNum = atoi(argv[paramCount++]);
		}
		else if (_stricmp(argv[paramCount], "--newfiles") == 0 || _stricmp(argv[paramCount], "-n") == 0) {
			paramCount++;
			theOutputter.setNewFilePerOpen();
		}
		else {
			printUsage();
			exit(2);
		}
	}

	if (paramCount >= argc) {
		printUsage();
		exit (2);
	}

	filename = argv[paramCount];

	// Initialise the XML system

	try {

		XMLPlatformUtils::Initialize();
#ifdef XSEC_HAVE_XALAN
		XPathEvaluator::initialize();
		XalanTransformer::initialize();
#endif
		XSECPlatformUtils::Initialise();

	}
	catch (const XMLException &e) {

		cerr << "Error during initialisation of Xerces" << endl;
		cerr << "Error Message = : "
		     << e.getMessage() << endl;

	}

	// Create and set up the parser

	XercesDOMParser * parser = new XercesDOMParser;
	
	parser->setDoNamespaces(true);
	parser->setCreateEntityReferenceNodes(true);

	// Now parse out file

	bool errorsOccured = false;
	XMLSize_t errorCount = 0;
    try
    {
    	parser->parse(filename);
        errorCount = parser->getErrorCount();
        if (errorCount > 0)
            errorsOccured = true;
    }

    catch (const XMLException& e)
    {
        cerr << "An error occurred during parsing\n   Message: "
             << e.getMessage() << endl;
        errorsOccured = true;
    }


    catch (const DOMException& e)
    {
       cerr << "A DOM error occurred during parsing\n   DOMException code: "
             << e.code << endl;
        errorsOccured = true;
    }

	if (errorsOccured) {

		cout << "Errors during parse" << endl;
		exit (2);

	}

	/*

		Now that we have the parsed file, get the DOM document and start looking at it

	*/
	
	DOMNode *doc;		// The document that we parsed

	doc = parser->getDocument();
	DOMDocument *theDOM = parser->getDocument();

	// Find the signature node
	
	DOMNode *sigNode = findDSIGNode(doc, "Signature");

	// Create the signature checker

	if (sigNode == 0) {

		cerr << "Could not find <Signature> node in " << argv[argc-1] << endl;
		exit(2);
	}

	XSECProvider prov;
	DSIGSignature * sig = prov.newSignatureFromDOM(theDOM, sigNode);
	sig->registerIdAttributeName(MAKE_UNICODE_STRING("ID"));

	// Map out base path of the file
#if XSEC_HAVE_GETCWD_DYN
	char *path = getcwd(NULL, 0);
	char *baseURI = (char*)malloc(strlen(path) + 8 + 1 + strlen(filename) + 1);
#else
	char path[PATH_MAX];
	char baseURI[(PATH_MAX * 2) + 10];
	getcwd(path, PATH_MAX);
#endif
	strcpy(baseURI, "file:///");
	strcat(baseURI, path);
	strcat(baseURI, "/");
	strcat(baseURI, filename);

	// Find any ':' and "\" characters
	int lastSlash = 0;
	for (unsigned int i = 8; i < strlen(baseURI); ++i) {
		if (baseURI[i] == '\\') {
			lastSlash = i;
			baseURI[i] = '/';
		}
		else if (baseURI[i] == '/')
			lastSlash = i;
	}

	// The last "\\" must prefix the filename
	baseURI[lastSlash + 1] = '\0';

	sig->getURIResolver()->setBaseURI(MAKE_UNICODE_STRING(baseURI));
#if XSEC_HAVE_GETCWD_DYN
	free(path);
	free(baseURI);
#endif


	try {

		XSECBinTXFMInputStream * is;
		XMLByte buf[1024];
		unsigned int sz;

		sig->load();
		if (references) {
			outputReferenceList(sig->getReferenceList(), theOutputter, refNum);

		}
		if (signedInfo) {
			is = sig->makeBinInputStream();
			if (is != NULL) {

				theOutputter.openSection();
				sz = (unsigned int) is->readBytes(buf, 1023);

				while (sz != 0) {
					
					buf[sz] = '\0';
					theOutputter.output(buf, sz);
	
					sz = (unsigned int) is->readBytes(buf, 1023);

				}
				theOutputter.closeSection();

				delete is;

			}
		}
	}

	catch (const XSECException &e) {
		char * m = XMLString::transcode(e.getMsg());
		cerr << "An error occurred during signature processing\n   Message: "
		<< m << endl;
		XSEC_RELEASE_XMLCH(m);
		errorsOccured = true;
		exit (2);
	}

	theOutputter.closeAll();

	prov.releaseSignature(sig);

	return 0;
}
