/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/




// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>
#include <com/sun/star/io/IOException.hpp>
#include <cppuhelper/implbase1.hxx>
#include <comphelper/processfactory.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <unotools/streamwrap.hxx>
#include <tools/debug.hxx>
#include "comphelper/anytostring.hxx"
#include "cppuhelper/exc_hlp.hxx"
#include "rtl/ref.hxx"

#include <svx/msdffimp.hxx>

#include "xmlconfig.hxx"

#include <stdio.h>
#include <ctype.h>
#include <stack>

using ::rtl::OUString;
using ::com::sun::star::io::XInputStream;
using ::com::sun::star::io::IOException;

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;

///////////////////////////////////////////////////////////////////////

AtomConfigMap gAtomConfigMap;

///////////////////////////////////////////////////////////////////////

class ConfigHandler : public ::cppu::WeakAggImplHelper1<XDocumentHandler>
{
public:
	// XDocumentHandler
	virtual void SAL_CALL startDocument(void) throw( SAXException, RuntimeException );
	virtual void SAL_CALL endDocument(void) throw( SAXException, RuntimeException );
	virtual void SAL_CALL startElement(const OUString& aName, const Reference< XAttributeList > & xAttribs) throw( SAXException, RuntimeException );
	virtual void SAL_CALL endElement(const OUString& aName) throw( SAXException, RuntimeException );
	virtual void SAL_CALL characters(const OUString& aChars) throw( SAXException, RuntimeException );
	virtual void SAL_CALL ignorableWhitespace(const OUString& aWhitespaces) throw( SAXException, RuntimeException );
	virtual void SAL_CALL processingInstruction(const OUString& aTarget, const OUString& aData) throw( SAXException, RuntimeException );
	virtual void SAL_CALL setDocumentLocator(const Reference< XLocator > & xLocator) throw( SAXException, RuntimeException );

private:
	void errorThrow( const OUString& rErrorMessage ) throw (SAXException );
	ElementConfigType parseType( const OUString& rErrorMessage ) throw ( SAXException );
	void addElement( ElementConfigPtr& rElementConfig ) throw ( SAXException );
	OUString getAttribute( const Reference< XAttributeList > & xAttribs, const sal_Char* pName ) throw( SAXException );

	ElementConfigPtr importAtomConfig( const Reference< XAttributeList > & xAttribs, bool bIsContainer ) throw( SAXException );
	ElementConfigPtr importElementConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
	ElementConfigPtr importSwitchConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
	ElementConfigPtr importCaseConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );
	ElementConfigPtr importValueElementConfig( const Reference< XAttributeList > & xAttribs ) throw( SAXException );

	std::stack< ElementConfigPtr > maElementStack;
};

void ConfigHandler::errorThrow( const OUString& rErrorMessage ) throw (SAXException )
{
	Reference< XInterface > aContext;
	Any aWrappedException;
    throw SAXException(rErrorMessage, aContext, aWrappedException);
}

ElementConfigType ConfigHandler::parseType( const OUString& sType ) throw (SAXException )
{
	if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("uint") ) )
	{
		return ECT_UINT;
	}
	else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("byte") ) )
	{
		return ECT_BYTE;
	}
	else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unistring") ) )
	{
		return ECT_UNISTRING;
	}
	else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("float") ) )
	{
		return ETC_FLOAT;
	}
	else if( sType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("hexdump") ) )
	{
	}
	else
	{
		OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "unknown type: " ) );
		aMessage += sType;
		errorThrow( aMessage );
	}

	return ECT_HEXDUMP;
}

void ConfigHandler::addElement( ElementConfigPtr& rElementConfig ) throw ( SAXException )
{
	ElementConfigContainer* pParent = dynamic_cast< ElementConfigContainer* >( maElementStack.top().get() );

	if( !pParent )
		errorThrow( OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal parent for element" ) ) );


	pParent->addElementConfig( rElementConfig );
}

OUString ConfigHandler::getAttribute( const Reference< XAttributeList > & xAttribs, const sal_Char* pName ) throw( SAXException )
{
	OUString aName( OUString::createFromAscii( pName ) );

	const sal_Int16 nAttrCount = xAttribs.is() ? xAttribs->getLength() : 0;
	sal_Int16 i;
	for(i=0; i < nAttrCount; i++)
	{
		if( xAttribs->getNameByIndex( i ) == aName )
			return xAttribs->getValueByIndex( i );
	}

	OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "missing required attribute: ") );
	aMessage += aName;
	errorThrow( aMessage );

	return OUString();
}

void SAL_CALL ConfigHandler::startDocument(void) throw( SAXException, RuntimeException )
{
}

void SAL_CALL ConfigHandler::endDocument(void) throw( SAXException, RuntimeException )
{
}

void SAL_CALL ConfigHandler::startElement(const OUString& aName, const Reference< XAttributeList > & xAttribs) throw( SAXException, RuntimeException )
{
	ElementConfigPtr pElement;

	if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "config" ) ) )
	{
		return;
	}

	if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "container" ) ) )
	{
		pElement = importAtomConfig( xAttribs, true );
	}
	else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "atom" ) ) )
	{
		pElement = importAtomConfig( xAttribs, false );
	}
	else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "element" ) ) )
	{
		pElement = importElementConfig( xAttribs );
	}
	else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "value" ) ) )
	{
		pElement = importValueElementConfig( xAttribs );
	}
	else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "switch" ) ) )
	{
		pElement = importSwitchConfig( xAttribs );
	}
	else if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "case" ) ) )
	{
		pElement = importCaseConfig( xAttribs );
	}

	if( !pElement.get() )
	{
		OUString aMessage( OUString( RTL_CONSTASCII_USTRINGPARAM("unknown config element: ")) );
		aMessage += aName;
		errorThrow( aMessage  );
	}

	maElementStack.push( pElement );
}

sal_Int32 toInt( const OUString& rText )
{
	if( rText.compareToAscii("0x",2) == 0)
	{
		sal_Int32 nValue = 0;
		const sal_Unicode *p = rText;
		p += 2;
		sal_Int32 nLength = rText.getLength() - 2;
		while( (nLength--) > 0 )
		{
			nValue <<= 4;
			if( *p >= '0' && *p <= '9' )
			{
				nValue += *p - '0';
			}
			else if( *p >= 'a' && *p <= 'f' )
			{
				nValue += *p - ('a' - 10);
			}
			else if( *p >= 'A' && *p <= 'F' )
			{
				nValue += *p - ('A' - 10 );
			}
			p++;
		}

		return nValue;
	}
	else
	{
		return rText.toInt32();
	}
}

ElementConfigPtr ConfigHandler::importAtomConfig( const Reference< XAttributeList > & xAttribs, bool bIsContainer ) throw (SAXException)
{
	if( !maElementStack.empty() )
		errorThrow( OUString( RTL_CONSTASCII_USTRINGPARAM("atom elements must be root" ) ) );

	ElementConfigPtr aPtr( new AtomConfig( getAttribute(xAttribs,"name"), bIsContainer ) );
	gAtomConfigMap[ (UINT16)toInt(getAttribute(xAttribs,"id"))] = aPtr;
	return aPtr;
}

ElementConfigPtr ConfigHandler::importElementConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
{
	ElementConfigType nType = parseType( getAttribute( xAttribs, "type" ) );
	ElementConfigPtr pElementConfig( new ElementConfigContainer( getAttribute( xAttribs, "name" ), nType ) );
	addElement( pElementConfig );
	return pElementConfig;
}

ElementConfigPtr ConfigHandler::importValueElementConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
{
	ElementConfigPtr pElementConfig( new ElementValueConfig( getAttribute( xAttribs, "name" ), getAttribute( xAttribs, "value" ) ) );
	addElement( pElementConfig );
	return pElementConfig;
}

ElementConfigPtr ConfigHandler::importSwitchConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
{
	ElementConfigType nType = parseType( getAttribute( xAttribs, "type" ) );
	ElementConfigPtr pElementConfig( new SwitchElementConfig( nType ) );
	addElement( pElementConfig );
	return pElementConfig;
}

ElementConfigPtr ConfigHandler::importCaseConfig( const Reference< XAttributeList > & xAttribs ) throw (SAXException)
{
	ElementConfigPtr pElementConfig( new CaseElementConfig( getAttribute( xAttribs, "value" ) ) );
	addElement( pElementConfig );
	return pElementConfig;	
}

void SAL_CALL ConfigHandler::endElement(const OUString& aName) throw( SAXException, RuntimeException )
{
	if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "config" ) ) )
	{
		return;
	}

	maElementStack.pop();
}

void SAL_CALL ConfigHandler::characters(const OUString& aChars) throw( SAXException, RuntimeException )
{
}

void SAL_CALL ConfigHandler::ignorableWhitespace(const OUString& aWhitespaces) throw( SAXException, RuntimeException )
{
}

void SAL_CALL ConfigHandler::processingInstruction(const OUString& aTarget, const OUString& aData) throw( SAXException, RuntimeException )
{
}

void SAL_CALL ConfigHandler::setDocumentLocator(const Reference< XLocator > & xLocator) throw( SAXException, RuntimeException )
{
}

void load_config( const OUString& rPath )
{
	try
	{
		// create stream
		SvStream*	pIStm = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ );
		Reference<XInputStream> xInputStream( new utl::OInputStreamWrapper( pIStm, sal_True ) );

		// prepare ParserInputSrouce
		InputSource aParserInput;
		aParserInput.sSystemId = rPath;
		aParserInput.aInputStream = xInputStream;

		// get parser
		Reference< XParser > xParser(
			comphelper::getProcessServiceFactory()->createInstance(
				OUString::createFromAscii("com.sun.star.xml.sax.Parser") ),
			UNO_QUERY_THROW );

		// get filter
		ConfigHandler* pConfigHandler = new ConfigHandler();
		Reference< XDocumentHandler > xFilter( pConfigHandler );

		// connect parser and filter
		xParser->setDocumentHandler( xFilter );

		// finally, parser the stream
		xParser->parseStream( aParserInput );
	}
	catch( Exception& r )
	{
		DBG_ERROR(
			(rtl::OString("load_config(), "
                     "exception caught: ") +
             rtl::OUStringToOString(
                 comphelper::anyToString( cppu::getCaughtException() ),
                 RTL_TEXTENCODING_UTF8 )).getStr() );

		(void)r;
	}
}

///////////////////////////////////////////////////////////////////////

rtl::OUString ElementConfig::format( SvStream& rStream, sal_Size& nLength ) const
{
	OUString aRet;
	if( maName.getLength() )
	{
		aRet += maName;
		aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( " = " ) );
	}

	switch( mnType )
	{
	case ECT_BYTE:		aRet += dump_byte( rStream, nLength ); break;
	case ECT_UINT:		aRet += dump_uint( rStream, nLength ); break;
	case ECT_UNISTRING:	aRet += dump_unistring( rStream, nLength ); break;
	case ETC_FLOAT:		aRet += dump_float( rStream, nLength ); break;
	case ECT_HEXDUMP:
	default:			aRet += dump_hex( rStream, nLength ); break;
	}

	return aRet;
}

rtl::OUString ElementConfig::dump_hex( SvStream& rStream, sal_Size& nLength )
{
	char buffer[128];
	OUString aOut, aEmpty;
	OUString aHex, aAscii;
	sal_Char c;
	int nRow = 0;
	while( nLength && (rStream.GetError() == 0) )
	{
		rStream >> c;
		nLength--;

		unsigned int i = c;
		i &= 0xff;
		sprintf( buffer, "%02x ", i );
		aHex += OUString::createFromAscii( buffer ); 

		if( !isprint( c ) )
			c = '.';

		aAscii += OUString( (sal_Unicode) c );
		nRow++;

		if( (nRow == 16) || (nLength==0) )
		{
			while( aHex.getLength() < (16*3) )
				aHex += OUString( RTL_CONSTASCII_USTRINGPARAM(" ") );
			aOut += aHex;
			aOut += aAscii;
			aOut += OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\r" ) );
			aHex = aEmpty;
			aAscii = aEmpty;
			nRow = 0;
		}
	}

	aOut += aHex;
	aOut += aAscii;

	return aOut;
}

rtl::OUString ElementConfig::dump_byte( SvStream& rStream, sal_Size& nLength )
{
	OUString aRet;
	if( nLength >= sizeof(sal_Char) )
	{
		sal_Char c;
		rStream >> c;

		char buffer[128];
		sprintf( buffer, "%u", (int)c );
		aRet += OUString::createFromAscii( buffer );
		nLength -= sizeof(sal_Char);
	}

	return aRet;
}

rtl::OUString ElementConfig::dump_uint( SvStream& rStream, sal_Size& nLength )
{
	OUString aRet;
	if( nLength >= sizeof( sal_uInt32 ) )
	{
		sal_uInt32 c;
		rStream >> c;

		char buffer[128];
		sprintf( buffer, "%u", c );
		aRet += OUString::createFromAscii( buffer );
		nLength-= sizeof( sal_uInt32 );
	}

	return aRet;
}

rtl::OUString ElementConfig::dump_unistring( SvStream& rStream, sal_Size& nLength )
{
	String aString;
	SvxMSDffManager::MSDFFReadZString( rStream, aString, nLength, sal_True );
	nLength = 0;
	return aString;
}

rtl::OUString ElementConfig::dump_float( SvStream& rStream, sal_Size& nLength )
{
	OUString aRet;
	if( nLength >= sizeof( float ) )
	{
		float c;
		rStream >> c;

		char buffer[128];
		sprintf( buffer, "%g", (double)c );
		aRet += OUString::createFromAscii( buffer );
		nLength-= sizeof( float );
	}

	return aRet;
}

///////////////////////////////////////////////////////////////////////

rtl::OUString ElementConfigContainer::format( SvStream& rStream, sal_Size& nLength ) const
{
	OUString aRet;

	if( getType() == ETC_CONTAINER )
	{

		ElementConfigList::const_iterator aIter( maElementConfigList.begin() );
		const ElementConfigList::const_iterator aEnd( maElementConfigList.end() );
		while( (aIter != aEnd) && (nLength > 0) )
		{
			aRet += (*aIter++)->format( rStream, nLength );
			if( (aIter != aEnd) || (nLength != 0) )
				aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( "\n\r" ) );
		}

		if( nLength )
			aRet += ElementConfig::dump_hex( rStream, nLength );
	}
	else
	{
		aRet = getName();
		if( aRet.getLength() )
			aRet += OUString( RTL_CONSTASCII_USTRINGPARAM( " = " ) );

		OUString aValue;
		switch( getType() )
		{
		case ECT_BYTE:		aValue = dump_byte( rStream, nLength ); break;
		case ECT_UINT:		aValue = dump_uint( rStream, nLength ); break;
		case ECT_UNISTRING:	aValue = dump_unistring( rStream, nLength ); break;
		case ETC_FLOAT:		aValue = dump_float( rStream, nLength ); break;
		case ECT_HEXDUMP:
		default:			aValue = dump_hex( rStream, nLength ); break;
		}

		if( aValue.getLength() )
		{
			if( !maElementConfigList.empty() )
			{
				ElementConfigList::const_iterator aIter( maElementConfigList.begin() );
				const ElementConfigList::const_iterator aEnd( maElementConfigList.end() );
				while( (aIter != aEnd) && (nLength > 0) )
				{
					ElementValueConfig* pValue = dynamic_cast< ElementValueConfig* >( (*aIter++).get() );
					if( pValue && pValue->getValue() == aValue )
					{
						aValue = pValue->getName();
						break;
					}
				}
			}
		}
		else
		{
			aValue = OUString( RTL_CONSTASCII_USTRINGPARAM("<empty!?>") );
		}

		aRet += aValue;
	}

	return aRet;
}

///////////////////////////////////////////////////////////////////////

rtl::OUString SwitchElementConfig::format( SvStream& rStream, sal_Size& nLength ) const
{
	OUString aValue;

	switch( getType() )
	{
	case ECT_BYTE:			aValue = dump_byte( rStream, nLength );	break;
	case ECT_UINT:			aValue = dump_uint( rStream, nLength ); break;
	case ETC_FLOAT:			aValue = dump_float( rStream, nLength ); break;
	case ECT_UNISTRING:		aValue = dump_unistring( rStream, nLength ); break;
	}

	if( aValue.getLength()  )
	{
		ElementConfigList::const_iterator aIter( maElementConfigList.begin() );
		const ElementConfigList::const_iterator aEnd( maElementConfigList.end() );
		while( (aIter != aEnd) && (nLength > 0) )
		{
			CaseElementConfig* pCase = dynamic_cast< CaseElementConfig* >( (*aIter++).get() );
			if( pCase && pCase->getValue() == aValue )
				return pCase->format( rStream, nLength );
		}
	}

	return ElementConfig::dump_hex( rStream, nLength );
}

