/**************************************************************
 * 
 * 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_xmloff.hxx"
#include <com/sun/star/embed/ElementModes.hpp>
#include <tools/debug.hxx>
#include <unotools/streamwrap.hxx>
#include <xmlversion.hxx>
#include <xmloff/xmlmetae.hxx>

#include <xmloff/xmltoken.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>

#include <tools/string.hxx>
class SvStringsDtor;

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

// ------------------------------------------------------------------------

sal_Char __FAR_DATA XMLN_VERSIONSLIST[] = "VersionList.xml";

// ------------------------------------------------------------------------

// #110897#
XMLVersionListExport::XMLVersionListExport(
	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
    const com::sun::star::uno::Sequence < com::sun::star::util::RevisionTag >& rVersions,
    const OUString &rFileName,
    Reference< XDocumentHandler > &rHandler )
:   SvXMLExport( xServiceFactory, rFileName, rHandler ),
	maVersions( rVersions ) 
{
    _GetNamespaceMap().AddAtIndex( XML_NAMESPACE_DC_IDX, xmloff::token::GetXMLToken(xmloff::token::XML_NP_DC),
                                   xmloff::token::GetXMLToken(xmloff::token::XML_N_DC), XML_NAMESPACE_DC );
    _GetNamespaceMap().AddAtIndex( XML_NAMESPACE_FRAMEWORK_IDX, xmloff::token::GetXMLToken(xmloff::token::XML_NP_VERSIONS_LIST),
                                   xmloff::token::GetXMLToken(xmloff::token::XML_N_VERSIONS_LIST), XML_NAMESPACE_FRAMEWORK );
}

// ------------------------------------------------------------------------
sal_uInt32 XMLVersionListExport::exportDoc( enum ::xmloff::token::XMLTokenEnum )
{
    GetDocHandler()->startDocument();

    sal_uInt16 nPos = _GetNamespaceMap().GetIndexByKey( XML_NAMESPACE_DC );

    AddAttribute( XML_NAMESPACE_NONE, _GetNamespaceMap().GetAttrNameByIndex( nPos ),
                             _GetNamespaceMap().GetNameByIndex ( nPos ) );

    nPos = _GetNamespaceMap().GetIndexByKey( XML_NAMESPACE_FRAMEWORK );
    AddAttribute( XML_NAMESPACE_NONE, _GetNamespaceMap().GetAttrNameByIndex( nPos ),
                             _GetNamespaceMap().GetNameByIndex ( nPos ) );

    {
        // the following object will write all collected attributes in its dtor
        SvXMLElementExport aRoot( *this, XML_NAMESPACE_FRAMEWORK, xmloff::token::XML_VERSION_LIST, sal_True, sal_True );

        for ( sal_Int32 n=0; n<maVersions.getLength(); n++ )
        {
            const util::RevisionTag& rInfo = maVersions[n];
            AddAttribute( XML_NAMESPACE_FRAMEWORK,
                          xmloff::token::XML_TITLE,
                          OUString( rInfo.Identifier ) );
            AddAttribute( XML_NAMESPACE_FRAMEWORK,
                          xmloff::token::XML_COMMENT,
                          OUString( rInfo.Comment ) );
            AddAttribute( XML_NAMESPACE_FRAMEWORK,
                          xmloff::token::XML_CREATOR,
                          OUString( rInfo.Author ) );

            OUString aDateStr =
                SvXMLMetaExport::GetISODateTimeString( rInfo.TimeStamp );

            AddAttribute( XML_NAMESPACE_DC, xmloff::token::XML_DATE_TIME, aDateStr );

            // the following object will write all collected attributes in its dtor
            SvXMLElementExport aEntry( *this, XML_NAMESPACE_FRAMEWORK, xmloff::token::XML_VERSION_ENTRY, sal_True, sal_True );
        }
    }
    GetDocHandler()->endDocument();
    return 0;
}

// ------------------------------------------------------------------------
// ------------------------------------------------------------------------

// #110897#
XMLVersionListImport::XMLVersionListImport(
	const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
    com::sun::star::uno::Sequence < com::sun::star::util::RevisionTag >& rVersions )
:	SvXMLImport(xServiceFactory),
    maVersions( rVersions )
{
    GetNamespaceMap().AddAtIndex( XML_NAMESPACE_FRAMEWORK_IDX, xmloff::token::GetXMLToken(xmloff::token::XML_NP_VERSIONS_LIST),
                                  xmloff::token::GetXMLToken(xmloff::token::XML_N_VERSIONS_LIST), XML_NAMESPACE_FRAMEWORK );
}

// ------------------------------------------------------------------------
XMLVersionListImport::~XMLVersionListImport( void ) throw()
{}

// ------------------------------------------------------------------------
SvXMLImportContext *XMLVersionListImport::CreateContext(
        sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const Reference< XAttributeList > & xAttrList )
{
    SvXMLImportContext *pContext = 0;

    if ( XML_NAMESPACE_FRAMEWORK == nPrefix &&
        rLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_VERSION_LIST) )
    {
        pContext = new XMLVersionListContext( *this, nPrefix, rLocalName, xAttrList );
    }
    else
    {
        pContext = SvXMLImport::CreateContext( nPrefix, rLocalName, xAttrList );
    }

    return pContext;
}


// ------------------------------------------------------------------------
// ------------------------------------------------------------------------

XMLVersionListContext::XMLVersionListContext( XMLVersionListImport& rImport,
                                        sal_uInt16 nPrefix,
                                        const OUString& rLocalName,
                                        const Reference< XAttributeList > & )
    : SvXMLImportContext( rImport, nPrefix, rLocalName )
    , rLocalRef( rImport )
{
}

// ------------------------------------------------------------------------
XMLVersionListContext::~XMLVersionListContext( void )
{}

// ------------------------------------------------------------------------
SvXMLImportContext *XMLVersionListContext::CreateChildContext( sal_uInt16 nPrefix,
                                        const OUString& rLocalName,
                                        const Reference< XAttributeList > & xAttrList )
{
    SvXMLImportContext *pContext = 0;

    if ( nPrefix == XML_NAMESPACE_FRAMEWORK &&
         rLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_VERSION_ENTRY) )
    {
        pContext = new XMLVersionContext( rLocalRef, nPrefix, rLocalName, xAttrList );
    }
    else
    {
        pContext = new SvXMLImportContext( rLocalRef, nPrefix, rLocalName );
    }

    return pContext;
}

// ------------------------------------------------------------------------
// ------------------------------------------------------------------------

XMLVersionContext::XMLVersionContext( XMLVersionListImport& rImport,
                                        sal_uInt16 nPref,
                                        const OUString& rLocalName,
                                        const Reference< XAttributeList > & xAttrList )
    : SvXMLImportContext( rImport, nPref, rLocalName )
    , rLocalRef( rImport )
{
    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;

    if ( !nAttrCount )
        return;

    util::RevisionTag aInfo;
    for ( sal_Int16 i=0; i < nAttrCount; i++ )
    {
        OUString        aLocalName;
        const OUString& rAttrName   = xAttrList->getNameByIndex( i );
        sal_uInt16      nPrefix     = rImport.GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );

        if ( XML_NAMESPACE_FRAMEWORK == nPrefix )
        {
            if ( aLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_TITLE) )
            {
                const OUString& rAttrValue = xAttrList->getValueByIndex( i );
                aInfo.Identifier = rAttrValue;
            }
            else if ( aLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_COMMENT) )
            {
                const OUString& rAttrValue = xAttrList->getValueByIndex( i );
                aInfo.Comment = rAttrValue;
            }
            else if ( aLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_CREATOR) )
            {
                const OUString& rAttrValue = xAttrList->getValueByIndex( i );
                aInfo.Author = rAttrValue;
            }
        }
        else if ( ( XML_NAMESPACE_DC == nPrefix ) &&
                  ( aLocalName == xmloff::token::GetXMLToken(xmloff::token::XML_DATE_TIME) ) )
        {
            const OUString& rAttrValue = xAttrList->getValueByIndex( i );
            util::DateTime aTime;
            if ( ParseISODateTimeString( rAttrValue, aTime ) )
                aInfo.TimeStamp = aTime;
        }
    }

    uno::Sequence < util::RevisionTag >& aList = rLocalRef.GetList();
    sal_Int32 nLength = aList.getLength();
    aList.realloc( nLength+1 );
    aList[nLength] = aInfo;
}


// ------------------------------------------------------------------------
XMLVersionContext::~XMLVersionContext( void )
{}

// ------------------------------------------------------------------------
// static
sal_Bool XMLVersionContext::ParseISODateTimeString(
                                const rtl::OUString& rString,
                                util::DateTime& rDateTime )
{
    sal_Bool bSuccess = sal_True;

    OUString aDateStr, aTimeStr;
    sal_Int32 nPos = rString.indexOf( (sal_Unicode) 'T' );
    if ( nPos >= 0 )
    {
        aDateStr = rString.copy( 0, nPos );
        aTimeStr = rString.copy( nPos + 1 );
    }
    else
        aDateStr = rString;         // no separator: only date part

    sal_Int32 nYear  = 0;
    sal_Int32 nMonth = 1;
    sal_Int32 nDay   = 1;
    sal_Int32 nHour  = 0;
    sal_Int32 nMin   = 0;
    sal_Int32 nSec   = 0;

    const sal_Unicode* pStr = aDateStr.getStr();
    sal_Int32 nDateTokens = 1;
    while ( *pStr )
    {
        if ( *pStr == '-' )
            nDateTokens++;
        pStr++;
    }
    if ( nDateTokens > 3 || aDateStr.getLength() == 0 )
        bSuccess = sal_False;
    else
    {
        sal_Int32 n = 0;
        nYear = aDateStr.getToken( 0, '-', n ).toInt32();
        if ( nYear > 9999 )
            bSuccess = sal_False;
        else if ( nDateTokens >= 2 )
        {
            nMonth = aDateStr.getToken( 0, '-', n ).toInt32();
            if ( nMonth > 12 )
                bSuccess = sal_False;
            else if ( nDateTokens >= 3 )
            {
                nDay = aDateStr.getToken( 0, '-', n ).toInt32();
                if ( nDay > 31 )
                    bSuccess = sal_False;
            }
        }
    }

    if ( bSuccess && aTimeStr.getLength() > 0 )         // time is optional
    {
        pStr = aTimeStr.getStr();
        sal_Int32 nTimeTokens = 1;
        while ( *pStr )
        {
            if ( *pStr == ':' )
                nTimeTokens++;
            pStr++;
        }
        if ( nTimeTokens > 3 )
            bSuccess = sal_False;
        else
        {
            sal_Int32 n = 0;
            nHour = aTimeStr.getToken( 0, ':', n ).toInt32();
            if ( nHour > 23 )
                bSuccess = sal_False;
            else if ( nTimeTokens >= 2 )
            {
                nMin = aTimeStr.getToken( 0, ':', n ).toInt32();
                if ( nMin > 59 )
                    bSuccess = sal_False;
                else if ( nTimeTokens >= 3 )
                {
                    nSec = aTimeStr.getToken( 0, ':', n ).toInt32();
                    if ( nSec > 59 )
                        bSuccess = sal_False;
                }
            }
        }
    }

    if ( bSuccess )
    {
        rDateTime.Day = sal::static_int_cast< sal_uInt16 >(nDay);
        rDateTime.Month = sal::static_int_cast< sal_uInt16 >(nMonth);
        rDateTime.Year = sal::static_int_cast< sal_uInt16 >(nYear);
        rDateTime.Hours = sal::static_int_cast< sal_uInt16 >(nHour);
        rDateTime.Minutes = sal::static_int_cast< sal_uInt16 >(nMin);
        rDateTime.Seconds = sal::static_int_cast< sal_uInt16 >(nSec);
    }

    return bSuccess;
}


// ------------------------------------------------------------------------
// ------------------------------------------------------------------------

void SAL_CALL XMLVersionListPersistence::store( const uno::Reference< embed::XStorage >& xRoot, const uno::Sequence< util::RevisionTag >& rVersions )
    throw (::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
{
    // no storage, no version list!
    if ( xRoot.is() )
    {
        // get the services needed for writing the xml data
        Reference< lang::XMultiServiceFactory > xServiceFactory =
                comphelper::getProcessServiceFactory();
        DBG_ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" );

        Reference< XInterface > xWriter (xServiceFactory->createInstance(
                OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))));
        DBG_ASSERT( xWriter.is(), "com.sun.star.xml.sax.Writer service missing" );

        // check wether there's already a sub storage with the version info
        // and delete it
        OUString sVerName( RTL_CONSTASCII_USTRINGPARAM( XMLN_VERSIONSLIST ) );

        // is this really needed, we set the size to zero before doing
        // anything with this stream?
/*      if ( xRoot->IsContained( sVerName ) )
        {
            xRoot->Remove( sVerName );
            xRoot->Commit();
        }
*/
		try {
        	// open (create) the sub storage with the version info
        	uno::Reference< io::XStream > xVerStream = xRoot->openStreamElement(
											sVerName,
											embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
			if ( !xVerStream.is() )
				throw uno::RuntimeException();

//REMOVE	        	// SetSize should not be neccessary because OpenStream( WRITE|TRUNC ) should already
//REMOVE	        	// have set the size to zero
//REMOVE		//      xVerStream->SetSize ( 0L );
//REMOVE	        	xVerStream->SetBufferSize( 16*1024 );

        	Reference< io::XOutputStream > xOut = xVerStream->getOutputStream();
			if ( !xOut.is() )
				throw uno::RuntimeException(); // the stream was successfuly opened for writing already

        	Reference< io::XActiveDataSource > xSrc( xWriter, uno::UNO_QUERY );
        	xSrc->setOutputStream(xOut);

        	Reference< XDocumentHandler > xHandler( xWriter, uno::UNO_QUERY );

            // XMLVersionListExport aExp( pList, sVerName, xHandler );
            XMLVersionListExport aExp( xServiceFactory, rVersions, sVerName, xHandler );

        	aExp.exportDoc( ::xmloff::token::XML_VERSION );

//REMOVE	        	xVerStream->Commit();
			xVerStream = uno::Reference< io::XStream >(); // use refcounting for now to dispose
	//      xRoot->Commit();
		}
		catch( uno::Exception& )
		{
            // TODO: error handling
		}
    }
}

// ------------------------------------------------------------------------
uno::Sequence< util::RevisionTag > SAL_CALL XMLVersionListPersistence::load( const uno::Reference< embed::XStorage >& xRoot )
        throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
{
    com::sun::star::uno::Sequence < com::sun::star::util::RevisionTag > aVersions;

    const OUString sDocName( RTL_CONSTASCII_USTRINGPARAM( XMLN_VERSIONSLIST ) );
	uno::Reference< container::XNameAccess > xRootNames( xRoot, uno::UNO_QUERY );

	try {
    	if ( xRootNames.is() && xRootNames->hasByName( sDocName ) && xRoot->isStreamElement( sDocName ) )
    	{
        	Reference< lang::XMultiServiceFactory > xServiceFactory =
                	comphelper::getProcessServiceFactory();
        	DBG_ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" );

        	InputSource aParserInput;

			uno::Reference< beans::XPropertySet > xProps( xRoot, uno::UNO_QUERY );
			OSL_ENSURE( xProps.is(), "Storage must implement XPropertySet!\n" );
			if ( xProps.is() )
			{
				try {
					xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "URL" ) ) >>= aParserInput.sSystemId;
				}
				catch( uno::Exception& )
				{}
			}

        	uno::Reference< io::XStream > xDocStream = xRoot->openStreamElement(
															sDocName,
															embed::ElementModes::READ );
			if ( !xDocStream.is() )
				throw uno::RuntimeException();

//REMOVE	        	xDocStream->Seek( 0L );
//REMOVE	        	xDocStream->SetBufferSize( 16*1024 );

        	aParserInput.aInputStream = xDocStream->getInputStream();
			OSL_ENSURE( aParserInput.aInputStream.is(),
						"The stream was successfuly opened for reading, the input part must be accessible!\n" );
			if ( !aParserInput.aInputStream.is() )
				throw uno::RuntimeException();

        	// get parser
        	Reference< XInterface > xXMLParser = xServiceFactory->createInstance(
            	OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
        	DBG_ASSERT( xXMLParser.is(),
            		"XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );

        	// get filter
            // Reference< XDocumentHandler > xFilter = new XMLVersionListImport( pList );
            Reference< XDocumentHandler > xFilter = new XMLVersionListImport( xServiceFactory, aVersions );

        	// connect parser and filter
        	Reference< XParser > xParser( xXMLParser, UNO_QUERY );
        	xParser->setDocumentHandler( xFilter );

        	// parse
        	try
        	{
            	xParser->parseStream( aParserInput );
        	}
        	catch( SAXParseException&  ) {}
        	catch( SAXException&  )      {}
        	catch( io::IOException& )    {}
    	}
	}
	catch( uno::Exception& )
	{
        // TODO: error handling
	}

    return aVersions;
}

uno::Sequence< rtl::OUString > SAL_CALL XMLVersionListPersistence_getSupportedServiceNames()
	throw()
{
	const rtl::OUString aServiceName(
        RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.DocumentRevisionListPersistence" ) );
	const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
	return aSeq;
}

rtl::OUString SAL_CALL XMLVersionListPersistence_getImplementationName() throw()
{
    return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLVersionListPersistence" ) );
}

uno::Reference< uno::XInterface > SAL_CALL XMLVersionListPersistence_createInstance(
		const uno::Reference< lang::XMultiServiceFactory > &)
	throw( uno::Exception )
{
    return (cppu::OWeakObject*)new XMLVersionListPersistence;
}

uno::Sequence< rtl::OUString > SAL_CALL XMLVersionImExportOOO_getSupportedServiceNames()
	throw()
{
	const rtl::OUString aServiceName(
        RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.DocumentRevisionListPersistence" ) );
	const uno::Sequence< rtl::OUString > aSeq( &aServiceName, 1 );
	return aSeq;
}

rtl::OUString SAL_CALL XMLVersionImExportOOO_getImplementationName() throw()
{
    return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMLVersionImExportOOo" ) );
}

uno::Reference< uno::XInterface > SAL_CALL XMLVersionImExportOOO_createInstance(
		const uno::Reference< lang::XMultiServiceFactory > &)
	throw( uno::Exception )
{
    return (cppu::OWeakObject*)new XMLVersionListPersistence;
}

