/**************************************************************
 *
 * 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 <tools/debug.hxx>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>

#ifndef _XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif
#include <xmloff/nmspmap.hxx>

#include "xmloff/xmlnmspe.hxx"


using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using namespace ::xmloff::token;

/* The basic idea of this class is that we have two two ways to search our
 * data...by prefix and by key. We use an STL hash_map for fast prefix
 * searching and an STL map for fast key searching.
 *
 * The references to an 'Index' refer to an earlier implementation of the
 * name space map and remain to support code which uses these interfaces.
 *
 * In this implementation, key and index should always be the same number.
 *
 * All references to Indices are now deprecated and the corresponding
 * 'Key' methods should be used instead
 *
 * Martin 13/06/01
 */

SvXMLNamespaceMap::SvXMLNamespaceMap()
: sXMLNS( GetXMLToken ( XML_XMLNS ) )
{
}

SvXMLNamespaceMap::SvXMLNamespaceMap( const SvXMLNamespaceMap& rMap )
: sXMLNS( GetXMLToken ( XML_XMLNS ) )
{
	aNameHash = rMap.aNameHash;
	aNameMap  = rMap.aNameMap;
}

void SvXMLNamespaceMap::operator=( const SvXMLNamespaceMap& rMap )
{
    aNameHash = rMap.aNameHash;
    aNameMap = rMap.aNameMap;
}

SvXMLNamespaceMap::~SvXMLNamespaceMap()
{
	QNameCache::iterator aIter = aQNameCache.begin(), aEnd = aQNameCache.end();
	while ( aIter != aEnd )
	{
		const OUString *pString = (*aIter).first.second;
		aIter++;
		delete pString;
    }
}

int SvXMLNamespaceMap::operator ==( const SvXMLNamespaceMap& rCmp ) const
{
	return static_cast < int > (aNameHash == rCmp.aNameHash);
}

sal_uInt16 SvXMLNamespaceMap::_Add( const OUString& rPrefix, const OUString &rName, sal_uInt16 nKey )
{
	if( XML_NAMESPACE_UNKNOWN == nKey )
	{
		// create a new unique key with UNKNOWN flag set
		nKey = XML_NAMESPACE_UNKNOWN_FLAG;
		do
		{
			NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey );
			if( aIter == aNameMap.end() )
				break;
			nKey++;
		}
		while ( sal_True );
	}
    ::vos::ORef<NameSpaceEntry> pEntry(new NameSpaceEntry);
	pEntry->sName   = rName;
	pEntry->nKey    = nKey;
	pEntry->sPrefix = rPrefix;
	aNameHash[ rPrefix ] = pEntry;
	aNameMap [ nKey ]	 = pEntry;
	return nKey;
}

sal_uInt16 SvXMLNamespaceMap::Add( const OUString& rPrefix, const OUString& rName,
							   sal_uInt16 nKey )
{
	if( XML_NAMESPACE_UNKNOWN == nKey )
		nKey = GetKeyByName( rName );

	DBG_ASSERT( XML_NAMESPACE_NONE != nKey,
				"SvXMLNamespaceMap::Add: invalid namespace key" );

	if( XML_NAMESPACE_NONE == nKey )
		return USHRT_MAX;

	if ( aNameHash.find ( rPrefix ) == aNameHash.end() )
		nKey = _Add( rPrefix, rName, nKey );

	return nKey;
}

sal_uInt16 SvXMLNamespaceMap::AddIfKnown( const OUString& rPrefix, const OUString& rName )
{
	sal_uInt16 nKey = GetKeyByName( rName );

	DBG_ASSERT( XML_NAMESPACE_NONE != nKey,
				"SvXMLNamespaceMap::AddIfKnown: invalid namespace key" );

	if( XML_NAMESPACE_NONE == nKey )
		return XML_NAMESPACE_UNKNOWN;

	if( XML_NAMESPACE_UNKNOWN != nKey )
    {
        NameSpaceHash::const_iterator aIter = aNameHash.find( rPrefix );
        if( aIter == aNameHash.end() || (*aIter).second->sName != rName )
            nKey = _Add( rPrefix, rName, nKey );
    }

	return nKey;
}


sal_uInt16 SvXMLNamespaceMap::GetKeyByPrefix( const OUString& rPrefix ) const
{
	NameSpaceHash::const_iterator aIter = aNameHash.find(rPrefix);
	return (aIter != aNameHash.end()) ? (*aIter).second->nKey : USHRT_MAX;
}

sal_uInt16 SvXMLNamespaceMap::GetKeyByName( const OUString& rName ) const
{
	sal_uInt16 nKey = XML_NAMESPACE_UNKNOWN;
	NameSpaceHash::const_iterator aIter = aNameHash.begin(), aEnd = aNameHash.end();
	while (aIter != aEnd )
	{
		if ((*aIter).second->sName == rName)
		{
			nKey = (*aIter).second->nKey;
			break;
		}
		aIter++;
	}
	return nKey;
}

const OUString& SvXMLNamespaceMap::GetPrefixByKey( sal_uInt16 nKey ) const
{
	NameSpaceMap::const_iterator aIter = aNameMap.find (nKey);
	return (aIter != aNameMap.end()) ? (*aIter).second->sPrefix : sEmpty;
}

const OUString& SvXMLNamespaceMap::GetNameByKey( sal_uInt16 nKey ) const
{
	NameSpaceMap::const_iterator aIter = aNameMap.find (nKey);
	return (aIter != aNameMap.end()) ? (*aIter).second->sName : sEmpty;
}

OUString SvXMLNamespaceMap::GetAttrNameByKey( sal_uInt16 nKey ) const
{
	OUStringBuffer sAttrName;
	NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey );
	if (aIter != aNameMap.end())
	{
		sAttrName.append( sXMLNS  );
        const ::rtl::OUString & prefix( (*aIter).second->sPrefix );
        if (prefix.getLength()) // not default namespace
        {
            sAttrName.append( sal_Unicode(':') );
            sAttrName.append( prefix );
        }
	}
	return sAttrName.makeStringAndClear();
}

OUString SvXMLNamespaceMap::GetQNameByKey( sal_uInt16 nKey,
							const OUString& rLocalName,
                            sal_Bool bCache) const
{
	// We always want to return at least the rLocalName...

	switch ( nKey )
	{
		case XML_NAMESPACE_UNKNOWN:
			// ...if it's a completely unknown namespace, assert and return the local name
			DBG_ASSERT( sal_False, "SvXMLNamespaceMap::GetQNameByKey: invalid namespace key" );
		case XML_NAMESPACE_NONE:
			// ...if there isn't one, return the local name
			return rLocalName;
		case XML_NAMESPACE_XMLNS:
		{
			// ...if it's in the xmlns namespace, make the prefix
			// don't bother caching this, it rarely happens
			OUStringBuffer sQName;
			sQName.append ( sXMLNS );
            if (rLocalName.getLength()) // not default namespace
            {
                sQName.append ( sal_Unicode(':') );
                sQName.append ( rLocalName );
            }
			return sQName.makeStringAndClear();
		}
		case XML_NAMESPACE_XML:
		{
            // this namespace is reserved, and needs not to be declared
			OUStringBuffer sQName;
			sQName.append ( GetXMLToken(XML_XML) );
			sQName.append ( sal_Unicode(':') );
			sQName.append ( rLocalName );
			return sQName.makeStringAndClear();
		}
		default:
		{
            QNameCache::const_iterator aQCacheIter;
            if (bCache)
			    aQCacheIter = aQNameCache.find ( QNamePair ( nKey, &rLocalName ) );
            else
                aQCacheIter = aQNameCache.end();
			if ( aQCacheIter != aQNameCache.end() )
				return (*aQCacheIter).second;
			else
			{
				NameSpaceMap::const_iterator aIter = aNameMap.find ( nKey );
				if ( aIter != aNameMap.end() )
				{
					OUStringBuffer sQName;
					// ...if it's in our map, make the prefix
                    const OUString & prefix( (*aIter).second->sPrefix );
                    if (prefix.getLength()) // not default namespace
                    {
                        sQName.append( prefix );
                        sQName.append( sal_Unicode(':') );
                    }
                    sQName.append ( rLocalName );
                    if (bCache)
                    {
                        OUString sString(sQName.makeStringAndClear());
                        OUString *pString = new OUString ( rLocalName );
                        const_cast < QNameCache * > (&aQNameCache)->operator[] ( QNamePair ( nKey, pString ) ) = sString;
                        return sString;
                    }
                    else
                        return sQName.makeStringAndClear();
				}
				else
				{
					// ... if it isn't, this is a Bad Thing, assert and return the local name
					DBG_ASSERT( sal_False, "SvXMLNamespaceMap::GetQNameByKey: invalid namespace key" );
					return rLocalName;
				}
			}
		}
	}
}

sal_uInt16 SvXMLNamespaceMap::_GetKeyByAttrName(
							const OUString& rAttrName,
							OUString *pLocalName,
                            sal_Bool bCache) const
{
	return _GetKeyByAttrName( rAttrName, 0, pLocalName, 0, bCache );
}

sal_uInt16 SvXMLNamespaceMap::_GetKeyByAttrName( const OUString& rAttrName,
											OUString *pPrefix,
											OUString *pLocalName,
											OUString *pNamespace,
                                            sal_Bool bCache) const
{
	sal_uInt16 nKey = XML_NAMESPACE_UNKNOWN;

    NameSpaceHash::const_iterator it;
    if (bCache)
        it = aNameCache.find ( rAttrName );
    else
        it = aNameCache.end();
    if ( it != aNameCache.end() )
	{
        const NameSpaceEntry &rEntry = (*it).second.getBody();
        if ( pPrefix )
            *pPrefix = rEntry.sPrefix;
        if ( pLocalName )
            *pLocalName = rEntry.sName;
        nKey = rEntry.nKey;
        if ( pNamespace )
		{
            NameSpaceMap::const_iterator aMapIter = aNameMap.find (nKey);
            *pNamespace = aMapIter != aNameMap.end() ? (*aMapIter).second->sName : sEmpty;
        }
    }
    else
    {
	vos::ORef<NameSpaceEntry> xEntry(new NameSpaceEntry());

        sal_Int32 nColonPos = rAttrName.indexOf( sal_Unicode(':') );
        if( -1L == nColonPos )
        {
            // case: no ':' found -> default namespace
            xEntry->sPrefix = OUString();
            xEntry->sName = rAttrName;
        }
        else
        {
            // normal case: ':' found -> get prefix/suffix
            xEntry->sPrefix = rAttrName.copy( 0L, nColonPos );
            xEntry->sName = rAttrName.copy( nColonPos + 1L );
        }

        if( pPrefix )
            *pPrefix = xEntry->sPrefix;
        if( pLocalName )
            *pLocalName = xEntry->sName;

        NameSpaceHash::const_iterator aIter = aNameHash.find( xEntry->sPrefix );
        if ( aIter != aNameHash.end() )
		{
            // found: retrieve namespace key
            nKey = xEntry->nKey = (*aIter).second->nKey;
            if ( pNamespace )
                *pNamespace = (*aIter).second->sName;
        }
        else if ( xEntry->sPrefix == sXMLNS )
            // not found, but xmlns prefix: return xmlns 'namespace'
            nKey = xEntry->nKey = XML_NAMESPACE_XMLNS;
        else if( nColonPos == -1L )
            // not found, and no namespace: 'namespace' none
            nKey = xEntry->nKey = XML_NAMESPACE_NONE;

        if (bCache)
	{
	    typedef std::pair< const rtl::OUString, vos::ORef<NameSpaceEntry> > value_type;
	    (void) const_cast<NameSpaceHash*>(&aNameCache)->insert (value_type (rAttrName, xEntry));
	}
    }

	return nKey;
}

sal_uInt16 SvXMLNamespaceMap::GetFirstKey() const
{
	return aNameMap.empty() ? USHRT_MAX : (*aNameMap.begin()).second->nKey;
}

sal_uInt16 SvXMLNamespaceMap::GetNextKey( sal_uInt16 nLastKey ) const
{
	NameSpaceMap::const_iterator aIter = aNameMap.find ( nLastKey );
	return (++aIter == aNameMap.end()) ? USHRT_MAX : (*aIter).second->nKey;
}


// All methods after this are deprecated...

sal_uInt16 SvXMLNamespaceMap::GetKeyByIndex( sal_uInt16 nIdx ) const
{
	return nIdx;
}

sal_uInt16 SvXMLNamespaceMap::GetIndexByKey( sal_uInt16 nKey ) const
{
	return nKey;
}
sal_uInt16 SvXMLNamespaceMap::GetFirstIndex() const
{
	return aNameMap.empty() ? USHRT_MAX : (*aNameMap.begin()).second->nKey;
}

sal_uInt16 SvXMLNamespaceMap::GetNextIndex( sal_uInt16 nOldIdx ) const
{
	NameSpaceMap::const_iterator aIter = aNameMap.find ( nOldIdx );
	return (++aIter == aNameMap.end()) ? USHRT_MAX : (*aIter).second->nKey;
}

sal_Bool SvXMLNamespaceMap::AddAtIndex( sal_uInt16 /*nIdx*/, const OUString& rPrefix,
									const OUString& rName, sal_uInt16 nKey )
{
	sal_Bool bRet = sal_False;

	if( XML_NAMESPACE_UNKNOWN == nKey )
		nKey = GetKeyByName( rName );

	DBG_ASSERT( XML_NAMESPACE_NONE != nKey,
				"SvXMLNamespaceMap::AddAtIndex: invalid namespace key" );
	if( XML_NAMESPACE_NONE != nKey && ! ( aNameHash.count ( rPrefix ) ) )
	{
		_Add( rPrefix, rName, nKey );
		bRet = sal_True;
	}
	return bRet;
}

sal_Bool SvXMLNamespaceMap::AddAtIndex( sal_uInt16 nIdx, const sal_Char *pPrefix,
					 				const sal_Char *pName, sal_uInt16 nKey )
{
	OUString sPrefix( OUString::createFromAscii(pPrefix) );
	OUString sName( OUString::createFromAscii(pName) );

	return AddAtIndex( nIdx, sPrefix, sName, nKey );
}

OUString SvXMLNamespaceMap::GetAttrNameByIndex( sal_uInt16 nIdx ) const
{
	return GetAttrNameByKey( nIdx );
}

OUString SvXMLNamespaceMap::GetQNameByIndex( sal_uInt16 nIdx,
										   const OUString& rLocalName ) const
{
	return GetQNameByKey( nIdx, rLocalName );
}

const OUString& SvXMLNamespaceMap::GetPrefixByIndex( sal_uInt16 nIdx ) const
{
	NameSpaceMap::const_iterator aIter = aNameMap.find (nIdx);
	return (aIter != aNameMap.end()) ? (*aIter).second->sPrefix : sEmpty;
}

const OUString& SvXMLNamespaceMap::GetNameByIndex( sal_uInt16 nIdx ) const
{
	NameSpaceMap::const_iterator aIter = aNameMap.find (nIdx);
	return (aIter != aNameMap.end()) ? (*aIter).second->sName : sEmpty;
}

sal_uInt16 SvXMLNamespaceMap::GetIndexByPrefix( const OUString& rPrefix ) const
{
	NameSpaceHash::const_iterator aIter = aNameHash.find(rPrefix);
	return (aIter != aNameHash.end()) ? (*aIter).second->nKey : USHRT_MAX;
}
sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName(
							const OUString& rAttrName,
							OUString *pLocalName,
							sal_uInt16 /*nIdxGuess*/) const
{
	return _GetKeyByAttrName( rAttrName, 0, pLocalName, 0 );
}

sal_uInt16 SvXMLNamespaceMap::GetKeyByAttrName( const OUString& rAttrName,
											OUString *pPrefix,
											OUString *pLocalName,
											OUString *pNamespace,
											sal_uInt16 /*nIdxGuess*/ ) const
{
	return _GetKeyByAttrName ( rAttrName, pPrefix, pLocalName, pNamespace );
}

sal_Bool SvXMLNamespaceMap::NormalizeURI( ::rtl::OUString& rName )
{
    // try OASIS + W3 URI normalization
    sal_Bool bSuccess = NormalizeOasisURN( rName );
    if( ! bSuccess )
        bSuccess = NormalizeW3URI( rName );
    return bSuccess;
}

sal_Bool SvXMLNamespaceMap::NormalizeW3URI( ::rtl::OUString& rName )
{
    // check if URI matches:
    // http://www.w3.org/[0-9]*/[:letter:]*
    //                   (year)/(WG name)
    // For the following WG/standards names:
    // - xforms

    sal_Bool bSuccess = sal_False;
	const OUString sURIPrefix = GetXMLToken( XML_URI_W3_PREFIX );
    if( rName.compareTo( sURIPrefix, sURIPrefix.getLength() ) == 0 )
    {
        const OUString sURISuffix = GetXMLToken( XML_URI_XFORMS_SUFFIX );
        sal_Int32 nCompareFrom = rName.getLength() - sURISuffix.getLength();
        if( rName.copy( nCompareFrom ).equals( sURISuffix ) )
        {
            // found W3 prefix, and xforms suffix
            rName = GetXMLToken( XML_N_XFORMS_1_0 );
            bSuccess = sal_True;
        }
    }
    return bSuccess;
}

sal_Bool SvXMLNamespaceMap::NormalizeOasisURN( ::rtl::OUString& rName )
{
	// #i38644#
	// we exported the wrong namespace for smil, so we correct this here on load
	// for older documents
	if( IsXMLToken( rName, ::xmloff::token::XML_N_SVG ) )
	{
		rName = GetXMLToken( ::xmloff::token::XML_N_SVG_COMPAT );
		return sal_True;
	}
	else if( IsXMLToken( rName, ::xmloff::token::XML_N_FO ) )
	{
		rName = GetXMLToken( ::xmloff::token::XML_N_FO_COMPAT );
		return sal_True;
	}
	else if( IsXMLToken( rName, ::xmloff::token::XML_N_SMIL ) ||
		  	 IsXMLToken( rName, ::xmloff::token::XML_N_SMIL_OLD )  )
	{
		rName = GetXMLToken( ::xmloff::token::XML_N_SMIL_COMPAT );
		return sal_True;
	}

	//
	// Check if URN matches
	// :urn:oasis:names:tc:[^:]*:xmlns:[^:]*:1.[^:]*
	//                     |---|       |---| |-----|
	//                     TC-Id      Sub-Id Version

	sal_Int32 nNameLen = rName.getLength();
	// :urn:oasis:names:tc.*
	const OUString& rOasisURN = GetXMLToken( XML_URN_OASIS_NAMES_TC );
	if( 0 != rName.compareTo( rOasisURN, rOasisURN.getLength() ) )
		return sal_False;

	// :urn:oasis:names:tc:.*
	sal_Int32 nPos = rOasisURN.getLength();
	if( nPos >= nNameLen || rName[nPos] != ':' )
		return sal_False;

	// :urn:oasis:names:tc:[^:]:.*
	sal_Int32 nTCIdStart = nPos+1;
	sal_Int32 nTCIdEnd = rName.indexOf( ':', nTCIdStart );
	if( -1 == nTCIdEnd )
		return sal_False;

	// :urn:oasis:names:tc:[^:]:xmlns.*
	nPos = nTCIdEnd + 1;
	OUString sTmp( rName.copy( nPos ) );
	const OUString& rXMLNS = GetXMLToken( XML_XMLNS );
	if( 0!= sTmp.compareTo( rXMLNS, rXMLNS.getLength() ) )
		return sal_False;

	// :urn:oasis:names:tc:[^:]:xmlns:.*
	nPos += rXMLNS.getLength();
	if( nPos >= nNameLen || rName[nPos] != ':' )
		return sal_False;

	// :urn:oasis:names:tc:[^:]:xmlns:[^:]*:.*
	nPos = rName.indexOf( ':', nPos+1 );
	if( -1 == nPos )
		return sal_False;

	// :urn:oasis:names:tc:[^:]:xmlns:[^:]*:[^:][^:][^:][^:]*
	sal_Int32 nVersionStart = nPos+1;
	if( nVersionStart+2 >= nNameLen ||
		-1 != rName.indexOf( ':', nVersionStart ) )
		return sal_False;

	// :urn:oasis:names:tc:[^:]:xmlns:[^:]*:1\.[^:][^:]*
	if( rName[nVersionStart] != '1' || rName[nVersionStart+1] != '.' )
		return sal_False;

	// replace [tcid] with current TCID and version with current version.
	OUStringBuffer aNewName( nNameLen +20 );
	aNewName.append( rName.copy( 0, nTCIdStart ) );
	aNewName.append( GetXMLToken( XML_OPENDOCUMENT ) );
	aNewName.append( rName.copy( nTCIdEnd, nVersionStart-nTCIdEnd ) );
	aNewName.append( GetXMLToken( XML_1_0 ) );

	rName = aNewName.makeStringAndClear();

	return sal_True;
}
