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



#include <osl/interlck.h>
#include	<rtl/alloc.h>
#include	<codemaker/dependency.hxx>

using namespace rtl;

TypeDependency::TypeDependency()
{
	m_pImpl = new TypeDependencyImpl();
	acquire();
}

TypeDependency::~TypeDependency()
{
	release();
}

void TypeDependency::acquire()
{
	osl_incrementInterlockedCount(&m_pImpl->m_refCount);
}

void TypeDependency::release()
{
	if (0 == osl_decrementInterlockedCount(&m_pImpl->m_refCount))
	{
		delete m_pImpl;
	}
}

sal_Bool TypeDependency::insert(const OString& type, const OString& depend, sal_uInt16 use)
{
	sal_Bool ret =  sal_False;

	if (type.getLength() > 0 && depend.getLength() > 0)
	{
		if (m_pImpl->m_dependencies.count(type) > 0)
		{
			TypeUsing typeUsing(depend, use);
			TypeUsingSet::iterator iter;
			if ((iter = m_pImpl->m_dependencies[type].find(typeUsing)) != m_pImpl->m_dependencies[type].end())
			{
  				(((TypeUsing *) &(*iter))->m_use) = (*iter).m_use | use;
			} else
			{
				m_pImpl->m_dependencies[type].insert(typeUsing);
			}
		} else
		{
			TypeUsing typeUsing(depend, use);
			TypeUsingSet tmpSet;
			tmpSet.insert(typeUsing);
			m_pImpl->m_dependencies[type]=tmpSet;
		}
	}

	return ret;
}

TypeUsingSet TypeDependency::getDependencies(const OString& type)
{
	if (type.getLength() > 0)
	{
		if (m_pImpl->m_dependencies.count(type) > 0)
		{
			return m_pImpl->m_dependencies[type];
		}
	}

	return TypeUsingSet();
}

sal_Bool TypeDependency::hasDependencies(const OString& type)
{
	if (type.getLength() > 0)
	{
		if (m_pImpl->m_dependencies.count(type) > 0)
		{
			return sal_True;
		}
	}

	return sal_False;
}

void TypeDependency::setGenerated(const OString& type, sal_uInt16 genFlag)
{
//	m_pImpl->m_generatedTypes.insert(type);
	if (m_pImpl->m_generatedTypes.count(type) > 0)
		m_pImpl->m_generatedTypes[type]= m_pImpl->m_generatedTypes[type] | genFlag;
	else
		m_pImpl->m_generatedTypes[type]=genFlag;
}

sal_Bool TypeDependency::isGenerated(const OString& type, sal_uInt16 genFlag)
{
/*
	if (m_pImpl->m_generatedTypes.count(type) > 0)
		return sal_True;

	return sal_False;
*/
	if (m_pImpl->m_generatedTypes.count(type) > 0 &&
		m_pImpl->m_generatedTypes[type] & genFlag)
	{
		return sal_True;
	}

	return sal_False;
}

static sal_Bool checkFieldDependencies(TypeManager& typeMgr, TypeDependency& dependencies,
									   TypeReader& reader, const OString& type)
{
	sal_uInt32 count = reader.getFieldCount();

	if (count == 0 || reader.getTypeClass() == RT_TYPE_ENUM)
		return sal_True;

	OString fieldType;
	for (sal_uInt16 i=0; i < count; i++)
	{
		fieldType = reader.getFieldType(i);

		if (fieldType.getLength() > 0)
		{
			dependencies.insert(type, fieldType, TYPEUSE_MEMBER);
			checkTypeDependencies(typeMgr, dependencies, fieldType);
		}
	}

	return sal_True;
}

static sal_Bool checkMethodDependencies(TypeManager& typeMgr, TypeDependency& dependencies,
									    TypeReader& reader, const OString& type)
{
	sal_uInt32 count = reader.getMethodCount();

	if (count == 0)
		return sal_True;

	OString returnType, paramType, excType;
	sal_uInt32 paramCount = 0;
	sal_uInt32 excCount = 0;
	RTParamMode paramMode = RT_PARAM_INVALID;
	for (sal_uInt16 i=0; i < count; i++)
	{
		returnType = reader.getMethodReturnType(i);

		dependencies.insert(type, returnType, TYPEUSE_RETURN);
		checkTypeDependencies(typeMgr, dependencies, returnType);

		paramCount = reader.getMethodParamCount(i);
		excCount = reader.getMethodExcCount(i);

		sal_uInt16 j;
		for (j=0; j < paramCount; j++)
		{
			paramType = reader.getMethodParamType(i, j);
			paramMode = reader.getMethodParamMode(i, j);

			switch (paramMode)
			{
				case RT_PARAM_IN:
					dependencies.insert(type, paramType, TYPEUSE_INPARAM);
					break;
				case RT_PARAM_OUT:
					dependencies.insert(type, paramType, TYPEUSE_OUTPARAM);
					break;
				case RT_PARAM_INOUT:
					dependencies.insert(type, paramType, TYPEUSE_INOUTPARAM);
					break;
                default:
                    break;
			}

			checkTypeDependencies(typeMgr, dependencies, paramType);
		}

		for (j=0; j < excCount; j++)
		{
			excType = reader.getMethodExcType(i, j);
			dependencies.insert(type, excType, TYPEUSE_EXCEPTION);
			checkTypeDependencies(typeMgr, dependencies, excType);
		}

	}

	return sal_True;
}

static sal_Bool checkReferenceDependencies(TypeManager& typeMgr, TypeDependency& dependencies,
										   TypeReader& reader, const OString& type)
{
	sal_uInt32 count = reader.getReferenceCount();

	if (count == 0)
		return sal_True;

	OString referenceName;
	for (sal_uInt16 i=0; i < count; i++)
	{
		referenceName = reader.getReferenceName(i);

		dependencies.insert(type, referenceName, TYPEUSE_NORMAL);
		checkTypeDependencies(typeMgr, dependencies, referenceName);
	}

	return sal_True;
}

sal_Bool checkTypeDependencies(TypeManager& typeMgr, TypeDependency& dependencies, const OString& type, sal_Bool bDepend)
{
	if (!typeMgr.isValidType(type))
		return sal_False;

	if (dependencies.hasDependencies(type))
		return sal_True;

	TypeReader reader = typeMgr.getTypeReader(type);

	if ( !reader.isValid() )
	{
		if (type.equals("/"))
			return sal_True;
		else
			return sal_False;
	}

    if ( bDepend && reader.getTypeClass() == RT_TYPE_MODULE)
    {
    	checkFieldDependencies(typeMgr, dependencies, reader, type);
        return sal_True;
    }

    for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) {
        OString superType(reader.getSuperTypeName(i));
		dependencies.insert(type, superType, TYPEUSE_SUPER);
		checkTypeDependencies(typeMgr, dependencies, superType);
	}

	if (reader.getTypeClass() == RT_TYPE_INTERFACE)
	{
		dependencies.insert(type, "com/sun/star/uno/RuntimeException", TYPEUSE_EXCEPTION);
		dependencies.insert(type, "com/sun/star/uno/TypeClass", TYPEUSE_NORMAL);
		checkTypeDependencies(typeMgr, dependencies, "com/sun/star/uno/RuntimeException", bDepend);
	}

	checkFieldDependencies(typeMgr, dependencies, reader, type);
	checkMethodDependencies(typeMgr, dependencies, reader, type);
	checkReferenceDependencies(typeMgr, dependencies, reader, type);

    // make the scope modules as dependencies
    sal_Int32 nPos = type.lastIndexOf( '/' );

	if ( nPos >= 0 )
	{
		OString aScope( type.copy( 0, nPos ) );
		OStringBuffer tmpBuf(aScope.getLength());

		nPos = 0;
		do
		{
			tmpBuf.append(aScope.getToken(0, '/', nPos));
			dependencies.insert(type, tmpBuf.getStr(), TYPEUSE_SCOPE);
			tmpBuf.append('/');
		} while( nPos != -1 );
    }

	return sal_True;
}
