//
// $Id: ProbeData.cpp,v 1.3 2004/10/18 14:25:10 bakerj Exp $
//
//************************** Property of the MITRE Corporation ***************************//
//
// Copyright (c) 2003 - The MITRE Corporation
//
// This file is part of the Query-based Network Assessment project.
//
// The Query-based Network Assessment is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License.
//
// The Query-based Network Assessment 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 the
// Query-based Network Assessment; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//****************************************************************************************//

#include "ProbeData.h"

//****************************************************************************************//
//								ProbeData Class											  //	
//****************************************************************************************//

//	Initialize the the namespace constant
#ifdef WIN32
	const string ProbeData::theNamespace = "http://oval.mitre.org/XMLSchema/system_characteristics#windows";
#endif

#ifdef REDHAT
	const string ProbeData::theNamespace = "http://oval.mitre.org/XMLSchema/system_characteristics#redhat";
#endif

#ifdef SOLARIS
	const string ProbeData::theNamespace = "http://oval.mitre.org/XMLSchema/system_characteristics#solaris";
#endif


ProbeData::ProbeData()
{
	// -----------------------------------------------------------------------
	//	ABSTRACT
	//
	//	Do nothing for now
	//
	// -----------------------------------------------------------------------

}

ProbeData::~ProbeData()
{
	// -----------------------------------------------------------------------
	//	ABSTRACT
	//
	//	Do nothing for now
	//
	// -----------------------------------------------------------------------

}

void ProbeData::SetTestId(string testIdIn)
{
	// -----------------------------------------------------------------------
	//	ABSTRACT
	//
	//	Set the test id for this object
	//
	// -----------------------------------------------------------------------
	testId = testIdIn;
}
	
string ProbeData::GetTestId()	
{
	// -----------------------------------------------------------------------
	//	ABSTRACT
	//
	//	Return the test id for the object
	//
	// -----------------------------------------------------------------------	
	
	return testId; 
}

void ProbeData::AddChildNode(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc, DOMNode *parent, string nodeName, string nodeValue, int dataType)
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Add a new DOMElement node to the parent node. Use nodeName and 
	//	nodeValue to construct the new node. Test the nodeValue. If the nodeValue
	//	is "" set the exists attribute to false. Add the datatype attribute if 
	//	not of type STRING_DATATYPE. 
	//	
	// -----------------------------------------------------------------------
	DOMText *tmpTextNode = NULL;
	DOMElement *newElem = NULL;
	string strDataType;

	//	Convert the datatype flag to a string.
	switch (dataType)
	{
		//	STRING_DATATYPE
		case 0: 
			strDataType = "";
			break;
		//	INTEGER_DATATYPE
		case 1:
			strDataType = "int";
			break;
		//	BINARY_DATATYPE
		case 2:
			strDataType = "binary";
			break;
		//	FLOAT_DATATYPE
		case 3:
			strDataType = "float";
			break;
		//	VERSION_DATATYPE
		case 4:
			strDataType = "version";
			break;
		default:
			throw ProbeDataException("Error: AddChildNode() Unsupported datatype specified. node name: " 
									+ nodeName 
									+ " value: " 
									+ nodeValue
									+ " parent node name: " 
									+ DOMCommon::ToString(parent->getNodeName()));
			break;
	}

	newElem = doc->createElement(XMLString::transcode(nodeName.c_str()));
	if(nodeValue.compare("") == 0 && nodeName.compare("filepath") != 0)
	{
		DOMCommon::AddAttribute(newElem, "exists", "false");
	}else
	{	
		//	Add the data type
		if(strDataType.compare("") != 0)
			DOMCommon::AddAttribute(newElem, "datatype", strDataType);

		tmpTextNode = doc->createTextNode(XMLString::transcode(nodeValue.c_str()));
		newElem->appendChild(tmpTextNode);
	}
	parent->appendChild(newElem);

}

DOMElement* ProbeData::CreateNewTestNode(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *dataDocument, string testName)
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Creat a new test node. Set the name to testName. Set the id to testId.
	//	Set the xmlns if desired.
	//
	// -----------------------------------------------------------------------

	//	Find the oval_data node
	DOMNode * oval_dataNode = DOMCommon::FindNode(dataDocument, "system_characteristics");

	//	Create the new test node and add to the oval_data node
	DOMElement *newTest = dataDocument->createElement(XMLString::transcode(testName.c_str()));
	oval_dataNode->appendChild(newTest);
	//	Add the test id
	DOMCommon::AddAttribute(newTest, "id", testId);

	//	Add the namespace information
	DOMCommon::AddAttribute(newTest, "xmlns", theNamespace);

	return newTest;
}

int ProbeData::DetermineDataType(string data)
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Examine the data string and determine the data type. Use regular 
	//	expression code in REGEX::IsMatch to determine if the 
	//	data is an integer, string, float, or binary.
	//	Default will be string.
	//
	// -----------------------------------------------------------------------
	if(data.compare("") == 0)
		return STRING_DATATYPE;

	int type;
	REGEX myMatcher;
 	
	//	Is the data binary - really means boolean
	if(myMatcher.IsMatch("^0|1$", data.c_str()))
	{
		type = BINARY_DATATYPE;
	//	Is the data an int
	}else if(myMatcher.IsMatch("^\\d+$", data.c_str()))
	{
		type = INTEGER_DATATYPE;
	//	Is the data a float
	}else if(myMatcher.IsMatch("^\\d*\\.\\d+$", data.c_str()))
	{
		type = FLOAT_DATATYPE;
	//	The data is a string
	}else 
	{
		type = STRING_DATATYPE;
	}

	return type;
}\

//****************************************************************************************//
//							ProbeDataException Class									  //	
//****************************************************************************************//
ProbeDataException::ProbeDataException() : Exception()
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Default constructor simply set the severity to ERROR_FATAL. This is 
	//	done with the explicit call to the Exception class default constructor.
	//
	// -----------------------------------------------------------------------

}

ProbeDataException::ProbeDataException(string errMsgIn) : Exception(errMsgIn)
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Set the error message and then set the severity to ERROR_FATAL. This is 
	//	done with the explicit call to the Exception class constructor that 
	//	takes a single string param.
	//
	// -----------------------------------------------------------------------

}

ProbeDataException::~ProbeDataException()
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Do nothing for now
	//
	// -----------------------------------------------------------------------

}

