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

#include "codemaker/commonjava.hxx"
#include "codemaker/commoncpp.hxx"
#include "codemaker/generatedtypeset.hxx"

#include "skeletoncommon.hxx"

#include <iostream>

using namespace ::rtl;
using namespace ::codemaker::cpp;

namespace skeletonmaker {

void printLicenseHeader(std::ostream& o, rtl::OString const & filename)
{
    sal_Int32 index = -1;
#ifdef SAL_UNX
	index = filename.lastIndexOf('/');
#else
	index = filename.lastIndexOf('\\');
#endif
    OString shortfilename(filename);
    if ( index != -1 )
        shortfilename = filename.copy(index+1);
                       
    o << "/**************************************************************\n"
        " * \n"
        " * Licensed to the Apache Software Foundation (ASF) under one\n"
        " * or more contributor license agreements.  See the NOTICE file\n"
        " * distributed with this work for additional information\n"
        " * regarding copyright ownership.  The ASF licenses this file\n"
        " * to you under the Apache License, Version 2.0 (the\n"
        " * \"License\"); you may not use this file except in compliance\n"
        " * with the License.  You may obtain a copy of the License at\n"
        " * \n"
        " *   http://www.apache.org/licenses/LICENSE-2.0\n"
        " * \n"
        " * Unless required by applicable law or agreed to in writing,\n"
        " * software distributed under the License is distributed on an\n"
        " * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n"
        " * KIND, either express or implied.  See the License for the\n"
        " * specific language governing permissions and limitations\n"
        " * under the License.\n"
        " * \n"
        " *************************************************************/\n\n";
}

bool getOutputStream(ProgramOptions const & options,
                     OString const & extension,
                     std::ostream** ppOutputStream,
                     OString & targetSourceFileName,
                     OString & tmpSourceFileName) 
{
    bool bStandardout = false;
    if ( options.outputpath.equals("stdout") )
    {
        bStandardout = true;
        *ppOutputStream = &std::cout;
        return bStandardout;
    }

    targetSourceFileName = createFileNameFromType(
        options.outputpath, options.implname.replace('.','/'), extension);

    OString tmpDir = getTempDir(targetSourceFileName);
    FileStream file;
    file.createTempFile(tmpDir);
        
    if( !file.isValid() )
    {
        OString message("cannot open ");
        message += targetSourceFileName + " for writing";
        throw CannotDumpException(message);
    } else {
        tmpSourceFileName = file.getName();
    }
    file.close();
    *ppOutputStream = new std::ofstream(tmpSourceFileName.getStr(),
                                        std::ios_base::binary);

    return bStandardout;
}

codemaker::UnoType::Sort decomposeResolveAndCheck(
    TypeManager const & manager, OString const & type,
    bool resolveTypedefs, bool allowVoid, bool allowExtraEntities,
    RTTypeClass * typeClass, OString * name, sal_Int32 * rank,
    std::vector< OString > * arguments)
{
    codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
        manager, type, resolveTypedefs, allowVoid, allowExtraEntities,
        typeClass, name, rank, arguments);
    for ( std::vector< OString >::iterator i(arguments->begin());
          i != arguments->end(); ++i )
    {
        RTTypeClass typeClass2;
        OString name2;
        sal_Int32 rank2;
        std::vector< OString > arguments2;
        decomposeResolveAndCheck(
            manager, *i, true, false, false, &typeClass2, &name2, &rank2,
            &arguments2);
    }
    return sort;
}

bool containsAttribute(AttributeInfo& attributes, OString const & attrname)
{
    for ( AttributeInfo::const_iterator i(attributes.begin());
          i != attributes.end(); ++i ) {
        if ( (*i).first == attrname ) {
            return true;
        }
    }
    return false;
}

// collect attributes including inherited attributes
void checkAttributes(TypeManager const & manager,
                     const typereg::Reader& reader,
                     AttributeInfo& attributes,
                     std::hash_set< OString, OStringHash >& propinterfaces)
{
    OString typeName = codemaker::convertString(reader.getTypeName());
    if ( typeName.equals("com/sun/star/beans/XPropertySet") ||
         typeName.equals("com/sun/star/beans/XFastPropertySet") ||
//        typeName.equals("com/sun/star/beans/XMultiPropertySet") ||
         typeName.equals("com/sun/star/beans/XPropertyAccess") )
    {
        propinterfaces.insert(typeName);
    }        
    
    for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
        typereg::Reader supertype(manager.getTypeReader(
                                  codemaker::convertString(
                                      reader.getSuperTypeName(i))));
        if ( !supertype.isValid() ) {
            throw CannotDumpException(
                "Bad type library entity "
                + codemaker::convertString(reader.getSuperTypeName(i)));
        }
        checkAttributes(manager, supertype, attributes, propinterfaces);
    }

    for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
        OString fieldName(
            codemaker::convertString(reader.getFieldName(i)).
            replace('/', '.'));

        if ( !containsAttribute(attributes, fieldName) ) {
            OString fieldType(
                codemaker::convertString(reader.getFieldTypeName(i)).
                replace('/', '.'));
            attributes.push_back(AttributeInfo::value_type(
                                     fieldName, std::pair<OString, sal_Int16>(
                                         fieldType, reader.getFieldFlags(i))));
        }
    }
}

void checkType(TypeManager const & manager,
               OString const & type,
               std::hash_set< OString, OStringHash >& interfaceTypes,
               std::hash_set< OString, OStringHash >& serviceTypes,
               AttributeInfo& properties)
{
    
    OString binType(type.replace('.', '/'));
    typereg::Reader reader(manager.getTypeReader(binType));
    if ( !reader.isValid() ) {
        throw CannotDumpException("Bad type library entity " + binType);
    }

    switch ( reader.getTypeClass() )
    {
    case RT_TYPE_INTERFACE:
    {
        // com/sun/star/lang/XComponent should be also not in the list
        // but it will be used for checking the impl helper and will be
        // removed later if necessary.
        if ( binType.equals("com/sun/star/lang/XTypeProvider") || 
             binType.equals("com/sun/star/uno/XWeak") )
            return;
        if (interfaceTypes.find(type) == interfaceTypes.end()) {
            interfaceTypes.insert(type);
        }
    }
        break;
    case RT_TYPE_SERVICE:
        if ( serviceTypes.find(binType) == serviceTypes.end() ) {
            serviceTypes.insert(binType);

            if ( reader.getSuperTypeCount() > 0 ) {
                OString supername(codemaker::convertString(
                    reader.getSuperTypeName(0).replace('/', '.')));
				if ( interfaceTypes.find(supername) == interfaceTypes.end() ) {
                    interfaceTypes.insert(supername);

					typereg::Reader supertype(manager.getTypeReader(
                                  codemaker::convertString(
                                      reader.getSuperTypeName(0))));
					if ( !supertype.isValid() ) {
						throw CannotDumpException(
							"Bad type library entity "
							+ codemaker::convertString(reader.getSuperTypeName(0)));
					}
				}

                // check if constructors are specified, if yes automatically
                // support of XInitialization. We will take care of the default
                // constructor because in this case XInitialization is not called. 
                if ( reader.getMethodCount() > 1 ||
                     ( reader.getMethodCount() == 1 &&
                       reader.getMethodName(0).getLength() > 0 ) )
                {
                    OString s("com.sun.star.lang.XInitialization");
                    if ( interfaceTypes.find(s) == interfaceTypes.end() )
                        interfaceTypes.insert(s);
                }                
            } else {
                for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) {
                    OString referenceType(
                        codemaker::convertString(
                            reader.getReferenceTypeName(i)).replace('/', '.'));
                    
                    if ( reader.getReferenceSort(i) == RT_REF_SUPPORTS ) {
                        checkType(manager, referenceType, interfaceTypes,
                                  serviceTypes, properties);
                    } else if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) {
                        checkType(manager, referenceType, interfaceTypes,
                                  serviceTypes, properties);
                    }
                }
                
                for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
                    OString fieldName(
                        codemaker::convertString(reader.getFieldName(i)).
                        replace('/', '.'));
                    OString fieldType(
                        codemaker::convertString(reader.getFieldTypeName(i)).
                        replace('/', '.'));

                    properties.push_back(AttributeInfo::value_type(
                        fieldName, std::pair<OString, sal_Int16>(
                            fieldType, reader.getFieldFlags(i))));
                }
            }
        }
        break;
    default:
        OSL_ASSERT(false);
        break;
    }
}

void checkDefaultInterfaces(
         std::hash_set< OString, OStringHash >& interfaces,
         const std::hash_set< OString, OStringHash >& services,
       const OString & propertyhelper)
{
    if ( services.empty() ) {
        if (interfaces.find("com.sun.star.lang.XServiceInfo") != interfaces.end())
            interfaces.erase("com.sun.star.lang.XServiceInfo");
    } else {
        if (interfaces.find("com.sun.star.lang.XServiceInfo") == interfaces.end())
            interfaces.insert("com.sun.star.lang.XServiceInfo");        
    }

    if ( propertyhelper.equals("_") ) {
        if (interfaces.find("com.sun.star.beans.XPropertySet")
            != interfaces.end())
            interfaces.erase("com.sun.star.beans.XPropertySet");
        if (interfaces.find("com.sun.star.beans.XFastPropertySet")
            != interfaces.end())
            interfaces.erase("com.sun.star.beans.XFastPropertySet");
        if (interfaces.find("com.sun.star.beans.XPropertyAccess")
            != interfaces.end())
            interfaces.erase("com.sun.star.beans.XPropertyAccess");
    }
}

bool checkServiceProperties(TypeManager const & manager,
                            const typereg::Reader & reader)
{
    if ( reader.getFieldCount() > 0 ) 
        return true;
    
    if ( reader.getReferenceCount() > 0 ) {
        for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) {
            if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) {
                typereg::Reader refreader(
                    manager.getTypeReader(
                        codemaker::convertString(reader.getReferenceTypeName(i))));

                if ( checkServiceProperties(manager, refreader) )
                    return true;
            }
        }                
    }
    return false;
}


OString checkPropertyHelper(
    ProgramOptions const & options,
    TypeManager const & manager,
    const std::hash_set< OString, OStringHash >& services,
    const std::hash_set< OString, OStringHash >& interfaces,
    AttributeInfo& attributes,
    std::hash_set< OString, OStringHash >& propinterfaces)
{
    std::hash_set< OString, OStringHash >::const_iterator iter;
    std::hash_set< OString, OStringHash >::const_iterator end;

    if ( !services.empty() ) {
        iter = services.begin();
        end = services.end();
    } else {
        iter = interfaces.begin();
        end = interfaces.end();        
    }

    bool oldStyleWithProperties = false;
    while ( iter != end ) {
        typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/')));

        if ( !services.empty() ) {
            if ( options.supportpropertysetmixin && reader.getSuperTypeCount() > 0 )
            {
                typereg::Reader supertype(
                    manager.getTypeReader(
                        codemaker::convertString(
                            reader.getSuperTypeName(0))));
                if ( !supertype.isValid() ) {
                    throw CannotDumpException(
                        "Bad type library entity "
                        + codemaker::convertString(
                            reader.getSuperTypeName(0)));
                }
                
                checkAttributes(manager, supertype, attributes, propinterfaces);
                
                if ( !(attributes.empty() || propinterfaces.empty()) ) {
                    return OUStringToOString(
                        supertype.getTypeName().replace('/', '.'),
                        osl_getThreadTextEncoding());
                }
            } else {
                oldStyleWithProperties = checkServiceProperties(manager, reader);
            }
        } else {
            checkAttributes(manager, reader, attributes, propinterfaces);
            if ( !(attributes.empty() || propinterfaces.empty()) ) {
                return OUStringToOString(
                    reader.getTypeName().replace('/', '.'),
                    osl_getThreadTextEncoding());
            }
        }
        iter++;
    }
    
    return (oldStyleWithProperties ? "_" : "");
}

bool checkXComponentSupport(TypeManager const & manager,
                            typereg::Reader const & reader)
{
    static OUString s(RTL_CONSTASCII_USTRINGPARAM(
                               "com/sun/star/lang/XComponent"));
    if ( reader.getTypeName().equals(s) )
        return true;

    for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
        typereg::Reader super(
            manager.getTypeReader(
                codemaker::convertString(
                    reader.getSuperTypeName(i))));
        if ( !super.isValid() ) {
            throw CannotDumpException(
                "Bad type library entity "
                + codemaker::convertString(
                    reader.getSuperTypeName(i)));
        }
        if ( checkXComponentSupport(manager, super) )
            return true;
    }

    return false;
}


// if XComponent is directly specified, return true and remove it from the
// supported interfaces list
bool checkXComponentSupport(TypeManager const & manager,
         std::hash_set< OString, OStringHash >& interfaces)
{
    if ( interfaces.empty() )
        return false;
        
    std::hash_set< OString, OStringHash >::const_iterator iter =
        interfaces.begin();
    while ( iter != interfaces.end() ) {
        if ( (*iter).equals("com.sun.star.lang.XComponent") ) {
            interfaces.erase("com.sun.star.lang.XComponent");
            return true;
        }            
        typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/')));
        if ( checkXComponentSupport(manager, reader) )
            return true;
        iter++;
    }

    return false;
}

sal_uInt16 checkAdditionalPropertyFlags(typereg::Reader const & reader,
                                        sal_uInt16 field, sal_uInt16 method)
{
    sal_uInt16 flags = 0;
    bool getterSupportsUnknown = false;
    
    OUString su(RTL_CONSTASCII_USTRINGPARAM(
                   "com/sun/star/beans/UnknownPropertyException"));
    if ( method < reader.getMethodCount()
         && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_GET
         && reader.getMethodName(method) == reader.getFieldName(field) )
    {
        if ( reader.getMethodExceptionCount(method) > 0 ) {
            for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method);
                  ++i )
            {
                if (su.equals(reader.getMethodExceptionTypeName(method, i)))
                    getterSupportsUnknown = true;
            }
        }
        method++;
    }
    if ( method < reader.getMethodCount()
         && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_SET
         && reader.getMethodName(method) == reader.getFieldName(field) )
    {
        if ( reader.getMethodExceptionCount(method) > 0 ) {
            OUString s(RTL_CONSTASCII_USTRINGPARAM(
                           "com/sun/star/beans/PropertyVetoException"));
            for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method);
                  ++i )
            {
                if ( s.equals(reader.getMethodExceptionTypeName(method, i)) )
                    flags |= RT_ACCESS_CONSTRAINED;
                if ( getterSupportsUnknown &&
                     su.equals(reader.getMethodExceptionTypeName(method, i)) )
                    flags |= RT_ACCESS_OPTIONAL;
            }
        }
    }
    return flags;
}

// This function checks if the specified types for paramters and return
// types are allowed add-in types, for more info see the com.sun.star.sheet.AddIn
// service description
bool checkAddinType(TypeManager const & manager,
                    OString const & type, bool & bLastAny,
                    bool & bHasXPropertySet, bool bIsReturn)
{
    RTTypeClass typeClass;
    OString name;
    sal_Int32 rank;
    std::vector< OString > arguments;
    codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
        manager, type, true, true, true, &typeClass, &name, &rank, &arguments);
    
    if ( sort == codemaker::UnoType::SORT_LONG ||
         sort == codemaker::UnoType::SORT_DOUBLE ||
         sort == codemaker::UnoType::SORT_STRING )
    {
        if ( rank == 0 || rank ==2 )
            return true;
    }
    if ( sort == codemaker::UnoType::SORT_ANY )
    {       
        if ( rank <= 2 ) {
            if ( rank ==1 ) {
                if ( bIsReturn )
                    return false;
                bLastAny = true;
            }
            
            return true;
        }
    }
    if ( sort == codemaker::UnoType::SORT_COMPLEX &&
         typeClass == RT_TYPE_INTERFACE )
    {
        if ( bIsReturn && type.equals("com/sun/star/sheet/XVolatileResult") )
            return true;
        if ( !bIsReturn && type.equals("com/sun/star/table/XCellRange") )
            return true;
        if ( !bIsReturn && type.equals("com/sun/star/beans/XPropertySet") )
        {
            if ( bHasXPropertySet ) {
                return false;
            } else {
                bHasXPropertySet = true;
                return true;
            }
        }
    }
    return false;
}

void checkAddInTypes(TypeManager const & manager,
                     typereg::Reader const & reader)
{ 
    OString sType(codemaker::convertString(reader.getTypeName()).replace('/', '.'));
    bool bLastAny = false;
    bool bHasXPropertySet = false;
    for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) {
        OString sMethod(codemaker::convertString(reader.getMethodName(m)));

        OString sReturnType(codemaker::convertString(
                                reader.getMethodReturnTypeName(m)));
        if ( !checkAddinType(
                 manager, sReturnType, bLastAny, bHasXPropertySet, true) )
        {
            OStringBuffer msg("the return type of the calc add-in function '");
            msg.append(sType);
            msg.append(":");
            msg.append(sMethod);
            msg.append("' is invalid. Please check your IDL defintion.");
            throw CannotDumpException(msg.makeStringAndClear());
        }

        bHasXPropertySet = false;
        for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) {
            bLastAny = false;
            OString sParamType(codemaker::convertString(
                                   reader.getMethodParameterTypeName(m, p)));
            if ( !checkAddinType(manager, sParamType,
                                bLastAny, bHasXPropertySet, false) ||
                 bLastAny )
            {
                OStringBuffer msg("the type of the ");
                msg.append((sal_Int32)p+1);
                msg.append(". parameter of the calc add-in function '");
                msg.append(sType);
                msg.append(":");
                msg.append(sMethod);
                msg.append("' is invalid.");
                if ( bLastAny )
                    msg.append(" The type 'sequence<any>' is allowed as last "
                               "parameter only.");
                if ( bHasXPropertySet )
                    msg.append(" The type 'XPropertySet' is allowed only once.");

                msg.append(" Please check your IDL definition.");                
                throw CannotDumpException(msg.makeStringAndClear());
            }
        }
    }
}

void generateFunctionParamterMap(std::ostream& o,
                                 ProgramOptions const & options,
                                 TypeManager const & manager,
                                 typereg::Reader const & reader,
                                 ::codemaker::GeneratedTypeSet & generated,
                                 bool bFirst)
{
    OString sType(codemaker::convertString(reader.getTypeName()));
    if ( sType.equals("com/sun/star/uno/XInterface") ||
         sType.equals("com/sun/star/lang/XLocalizable") ||
         sType.equals("com/sun/star/lang/XServiceInfo") ||
         // the next three checks becomes obsolete when configuration is used
         sType.equals("com/sun/star/sheet/XAddIn") ||
         sType.equals("com/sun/star/sheet/XCompatibilityNames") ||
         sType.equals("com/sun/star/lang/XServiceName") )
    {
        return;
    }

    // check if the specified add-in functions supports valid types
    checkAddInTypes(manager, reader);
    
    for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
        typereg::Reader super(
            manager.getTypeReader(
                codemaker::convertString(
                    reader.getSuperTypeName(i))));
        if ( !super.isValid() ) {
            throw CannotDumpException(
                "Bad type library entity "
                + codemaker::convertString(
                    reader.getSuperTypeName(i)));
        } 
        generateFunctionParamterMap(o, options, manager, super, generated, bFirst);
    }

    OString type(codemaker::convertString(reader.getTypeName()));
    if ( generated.contains(type) )
        return;
    else
        generated.add(type);

    for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) {
        OString sMethod(codemaker::convertString(reader.getMethodName(m)));

        if ( bFirst ) {
            if (options.language == 2) {
                o << "        ParamMap fpm;\n";
            }
            else {
                if ( options.java5 )
                    o << "        java.util.Hashtable< Integer, String > fpm = "
                        "new java.util.Hashtable< Integer, String >();\n";
                else
                    o << "        java.util.Hashtable fpm = "
                        "new java.util.Hashtable();\n";
            }
            bFirst = false;
        } else
            if ( options.language == 2 ) {
                o << "        fpm = ParamMap();\n";
            }
            else {
                if ( options.java5 )
                    o << "        fpm = new java.util.Hashtable< "
                        "Integer, String >();\n";
                else
                    o << "        fpm = new java.util.Hashtable();\n";
            }
            
        for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) {
            if ( options.language == 2 ) {
                o << "        fpm[" << p
                  << "] = ::rtl::OUString::createFromAscii(\""
                  << codemaker::convertString(reader.getMethodParameterName(m, p))
                  << "\");\n";
            }
            else {
                if ( options.java5 )
                    o << "        fpm.put(" << p << ", \""
                      << codemaker::convertString(
                          reader.getMethodParameterName(m, p))
                      << "\");\n";
                else
                    o << "       fpm.put(new Integer(" << p << "), \""
                      << codemaker::convertString(
                          reader.getMethodParameterName(m, p))
                      << "\");\n";
            }
        }

        if ( options.language == 2 ) {
            o << "        m_functionMap[::rtl::OUString::createFromAscii(\""
              << sMethod << "\")] = fpm;\n\n";
        }
        else {
            o << "        m_functionMap.put(\"" << sMethod << "\", fpm);\n\n";
        }
    }
}

void generateFunctionParameterMap(std::ostream& o,
         ProgramOptions const & options,
         TypeManager const & manager,
         const std::hash_set< OString, OStringHash >& interfaces)
{
    ::codemaker::GeneratedTypeSet generated;
    bool bFirst = true;
    std::hash_set< OString, OStringHash >::const_iterator iter = interfaces.begin();
    while ( iter != interfaces.end() ) {
        typereg::Reader reader(manager.getTypeReader((*iter).replace('.','/')));
        if (!reader.isValid()) {
            throw CannotDumpException(
                "Bad type library entity "
                + codemaker::convertString(
                    reader.getTypeName()));
        }
        
        generateFunctionParamterMap(o, options, manager, reader, generated, bFirst);
        iter++;
    }
}

}

