/**************************************************************
 *
 * 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_cppumaker.hxx"

#include <stdio.h>

#include "sal/main.h"

#include "codemaker/typemanager.hxx"
#include "codemaker/generatedtypeset.hxx"

#include "cppuoptions.hxx"
#include "cpputype.hxx"

using namespace rtl;

namespace {

void failed(rtl::OString const & typeName, CppuOptions * options) {
    fprintf(stderr, "%s ERROR: %s\n", options->getProgramName().getStr(),
            rtl::OString("cannot dump Type '" + typeName + "'").getStr());
    exit(99);
}

void produce(
    RegistryKey& rTypeKey, bool bIsExtraType, TypeManager const & typeMgr,
    codemaker::GeneratedTypeSet & generated, CppuOptions * options)
{
    if (!produceType(rTypeKey, bIsExtraType, typeMgr, generated, options)) {
        OString typeName = typeMgr.getTypeName(rTypeKey);
        failed(typeName, options);
    }
}

void produce(
    rtl::OString const & typeName, TypeManager const & typeMgr,
    codemaker::GeneratedTypeSet & generated, CppuOptions * options)
{
    if (!produceType(typeName, typeMgr, generated, options)) {
        failed(typeName, options);
    }
}

void produceAllTypes(RegistryKey& rTypeKey, bool bIsExtraType,
						 TypeManager const & typeMgr,
                         codemaker::GeneratedTypeSet & generated,
						 CppuOptions* pOptions,
						 sal_Bool bFullScope)
	throw( CannotDumpException )
{
    OString typeName = typeMgr.getTypeName(rTypeKey);

    produce(rTypeKey, bIsExtraType, typeMgr, generated, pOptions);

    RegistryKeyList typeKeys = typeMgr.getTypeKeys(typeName);
	RegistryKeyList::const_iterator iter = typeKeys.begin();
    RegistryKey key, subKey;
    RegistryKeyArray subKeys;

	while (iter != typeKeys.end())
	{
        key = (*iter).first;

        if (!(*iter).second  && !key.openSubKeys(OUString(), subKeys))
        {
            for (sal_uInt32 i = 0; i < subKeys.getLength(); i++)
            {
                subKey = subKeys.getElement(i);
                if (bFullScope)
                {
                    produceAllTypes(subKey, (*iter).second, typeMgr,
                                    generated, pOptions, true);
                } else
                {
                    produce(subKey, (*iter).second,
                            typeMgr, generated, pOptions);
                }
            }
        }

        ++iter;
	}
}

void produceAllTypes(const OString& typeName,
                     TypeManager const & typeMgr,
                     codemaker::GeneratedTypeSet & generated,
                     CppuOptions* pOptions,
                     sal_Bool bFullScope)
	throw( CannotDumpException )
{
    produce(typeName, typeMgr, generated, pOptions);

    RegistryKeyList typeKeys = typeMgr.getTypeKeys(typeName);
	RegistryKeyList::const_iterator iter = typeKeys.begin();
    RegistryKey key, subKey;
    RegistryKeyArray subKeys;

	while (iter != typeKeys.end())
	{
        key = (*iter).first;
        if (!(*iter).second  && !key.openSubKeys(OUString(), subKeys))
        {
            for (sal_uInt32 i = 0; i < subKeys.getLength(); i++)
            {
                subKey = subKeys.getElement(i);
                if (bFullScope)
                {
                    produceAllTypes(subKey, (*iter).second, typeMgr,
                                    generated, pOptions, true);
                } else
                {
                    produce(subKey, (*iter).second,
                            typeMgr, generated, pOptions);
                }
            }
        }

        ++iter;
	}
}

}

SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
{
	CppuOptions options;

	try
	{
		if (!options.initOptions(argc, argv))
		{
			exit(1);
		}
	}
	catch( IllegalArgument& e)
	{
		fprintf(stderr, "Illegal option: %s\n", e.m_message.getStr());
		exit(99);
	}

	RegistryTypeManager typeMgr;

	if (!typeMgr.init(options.getInputFiles(), options.getExtraInputFiles()))
	{
		fprintf(stderr, "%s : init registries failed, check your registry files.\n", options.getProgramName().getStr());
		exit(99);
	}

	if (options.isValid("-B"))
	{
		typeMgr.setBase(options.getOption("-B"));
	}

    codemaker::GeneratedTypeSet generated;
	try
	{
		if (options.isValid("-T"))
		{
			OString tOption(options.getOption("-T"));

			OString typeName, tmpName;
            sal_Int32 nIndex = 0;
            do
			{
				typeName = tOption.getToken(0, ';', nIndex);

                sal_Int32 nPos = typeName.lastIndexOf( '.' );
                tmpName = typeName.copy( nPos != -1 ? nPos+1 : 0 );
				if (tmpName == "*")
				{
					// produce this type and his scope
					if (typeName.equals("*"))
					{
						tmpName = "/";
					} else
					{
						tmpName = typeName.copy(0, typeName.lastIndexOf('.')).replace('.', '/');
						if ( tmpName.isEmpty() )
							tmpName = "/";
						else
							tmpName.replace('.', '/');
					}
                    // related to task #116780# the scope is recursively
                    // generated.  bFullScope = true
					produceAllTypes(
                        tmpName, typeMgr, generated, &options, true);
				} else
				{
					// produce only this type
                    produce(
                        typeName.replace('.', '/'), typeMgr, generated, &options);
				}
			} while( nIndex != -1 );
		} else
		{
			// produce all types
			produceAllTypes("/", typeMgr, generated, &options, true);
		}
        // C++ header files generated for the following UNO types are included
        // in header files in cppu/inc/com/sun/star/uno (Any.hxx, Reference.hxx,
        // Type.h), so it seems best to always generate those C++ header files:
        produce("com/sun/star/uno/RuntimeException", typeMgr, generated, &options);
        produce("com/sun/star/uno/TypeClass", typeMgr, generated, &options);
        produce("com/sun/star/uno/XInterface", typeMgr, generated, &options);
	}
	catch( CannotDumpException& e)
	{
		fprintf(stderr, "%s ERROR: %s\n",
				options.getProgramName().getStr(),
				e.m_message.getStr());
		exit(99);
	}

	return 0;
}
