/**************************************************************
 *
 * 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 <vcl/svapp.hxx>

// This works and was used before for standalone test, not sure why
// we'd want it.
#define LAYOUT_WEAK 1
#include "uno.hxx"

#include <cstdio>
#include <cstdlib>
#include <sys/stat.h>

#include <com/sun/star/xml/sax/SAXException.hpp>
#include <comphelper/processfactory.hxx>
#include <cppuhelper/bootstrap.hxx>
#include <rtl/ustring.hxx>
#include <ucbhelper/configurationkeys.hxx>
#include <ucbhelper/contentbroker.hxx>

#define SORT_DLG 1 /* requires sfx2, svx to be compiled */
#if SORT_DLG
#include "scitems.hxx"
#include "uiitems.hxx"
#endif /* SORT_DLG */

#include "editor.hxx"

#include "plugin.hxx"
#undef _LAYOUT_POST_HXX

#include "recover.hxx"
#undef _LAYOUT_POST_HXX

#if SORT_DLG
#include "sortdlg.hxx"
#undef _LAYOUT_POST_HXX
#endif /* SORT_DLG */

#include "wordcountdialog.hxx"
#undef _LAYOUT_POST_HXX

#include "zoom.hxx"
#undef _LAYOUT_POST_HXX

#include <layout/layout-pre.hxx>

using namespace ::rtl;
using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

class LayoutTest : public Application
{
    Reference< XComponentContext > mxContext;
    Reference< lang::XMultiServiceFactory > mxMSF;
    OUString mInstallDir;
    OUString mTestDialog;
    bool mEditMode;
    std::list< OUString > mFiles;

public:
    LayoutTest( char const* installDir );

    void RunEditor();
    void RunFiles();
    void ExceptionalMain();
    void Init();
    void InitUCB();
    void LoadFile( OUString const &aName );
    void Main();
    void ParseCommandLine();
};

static void usage()
{
    fprintf (stderr, "usage: test [--inst OOO_INSTALL_PREFIX] [DIALOG.XML]... | --test [DIALOG.XML]\n" );
    exit( 2 );
}

static uno::Reference< lang::XSingleServiceFactory > get_factory( char const *service )
{
    uno::Reference< lang::XSingleServiceFactory > xFactory(
        comphelper::createProcessComponent(
            rtl::OUString::createFromAscii( service ) ), uno::UNO_QUERY );

    if ( !xFactory.is() )
        fprintf( stderr, "error loading: %s\n", service );
    return xFactory;
}

#define GET_FACTORY(x) get_factory( #x )

void LayoutTest::LoadFile( const OUString &aTestFile )
{
    fprintf( stderr, "TEST: layout instance\n" );

    uno::Reference< lang::XSingleServiceFactory > xFactory
        = GET_FACTORY( com.sun.star.awt.Layout );
    if ( !xFactory.is() )
    {
        fprintf( stderr, "Layout engine not installed\n" );
        throw uno::RuntimeException(
            rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Layout engine not installed" ) ),
            uno::Reference< uno::XInterface >() );
    }
    fprintf( stderr, "TEST: initing root\n" );

    uno::Sequence< uno::Any > aParams( 1 );
    aParams[0] <<= aTestFile;

    uno::Reference< awt::XLayoutRoot > xRoot (
        xFactory->createInstanceWithArguments( aParams ),
        uno::UNO_QUERY );

    fprintf( stderr, "TEST: file loaded\n" );
}

void LayoutTest::InitUCB()
{
    OUString aEmpty;
    Sequence< Any > aArgs( 6 );
    aArgs[0]
        <<= OUString::createFromAscii( UCB_CONFIGURATION_KEY1_LOCAL );
    aArgs[1]
        <<= OUString::createFromAscii( UCB_CONFIGURATION_KEY2_OFFICE );
    aArgs[2] <<= OUString::createFromAscii( "PIPE" );
    aArgs[3] <<= aEmpty;
    aArgs[4] <<= OUString::createFromAscii( "PORTAL" );
    aArgs[5] <<= aEmpty;

    if ( !::ucbhelper::ContentBroker::initialize( mxMSF, aArgs ) )
    {
        fprintf( stderr, "Failed to init content broker\n" );
        fprintf( stderr, "arg[0]: %s\n", UCB_CONFIGURATION_KEY1_LOCAL );
        fprintf( stderr, "arg[1]: %s\n", UCB_CONFIGURATION_KEY2_OFFICE );
    }
}

static void support_upstream_brand_prefix ()
{
    if ( char const* inst = getenv( "OOO_INSTALL_PREFIX" ) )
    {
        char const *brand_prefix = "/openoffice.org3";
        OUString brand_dir = OUString::createFromAscii( inst )
            + OUString::createFromAscii( brand_prefix );
        struct stat stat_info;
        if ( !stat ( OUSTRING_CSTR( brand_dir ), &stat_info ) )
        {
            OSL_TRACE( "Appending %s to OOO_INSTALL_PREFIX", brand_prefix );
            setenv( "OOO_INSTALL_PREFIX", OUSTRING_CSTR( brand_dir ), 1 );
        }
    }
}

void LayoutTest::Init()
{
    ParseCommandLine();
    setenv( "OOO_INSTALL_PREFIX", OUSTRING_CSTR( mInstallDir ), 0 );
    support_upstream_brand_prefix ();
    OSL_TRACE( "OOO_INSTALL_PREFIX=%s", getenv( "OOO_INSTALL_PREFIX" ) );

    mxContext = defaultBootstrap_InitialComponentContext();
    mxMSF = new UnoBootstrapLayout( Reference< lang::XMultiServiceFactory >( mxContext->getServiceManager(), UNO_QUERY ) );
    ::comphelper::setProcessServiceFactory( mxMSF );
    InitUCB();
}

void LayoutTest::ParseCommandLine()
{
    printf ("%s\n", __PRETTY_FUNCTION__);
    for ( sal_uInt16 i = 0; i < GetCommandLineParamCount(); i++ )
    {
        OUString aParam = OUString( GetCommandLineParam( i ) );
        if ( aParam.equalsAscii( "-h" ) || aParam.equalsAscii( "--help" ) )
            usage();
        if ( aParam.equalsAscii( "--inst" ) )
        {
            if ( i >= GetCommandLineParamCount() - 1)
                usage();
            mInstallDir = GetCommandLineParam( ++i );
            setenv( "OOO_INSTALL_PREFIX", OUSTRING_CSTR( mInstallDir ), 1 );
        }
        else if ( aParam.equalsAscii( "--test" ) )
        {
            mTestDialog = OUString::createFromAscii( "zoom" );
            if (i + 1 < GetCommandLineParamCount())
                mTestDialog = GetCommandLineParam( ++i );
        }
        else if ( aParam.equalsAscii( "--editor" ) )
            mEditMode = true;
        else
            mFiles.push_back( aParam );
    }

    if ( mFiles.size() <= 0 )
        mFiles.push_back( OUString::createFromAscii( "layout.xml" ) );
}

void LayoutTest::RunEditor()
{
    OUString aFile;
    if ( !mFiles.empty()
        && mFiles.front().compareToAscii( "layout.xml" ) != 0 )
        aFile = mFiles.front();
    Editor editor( mxMSF, aFile );
    editor.Show();
    editor.Execute();
}

short RunDialog( Dialog& dialog )
{
    dialog.Show();
    short result = dialog.Execute();
    fprintf( stderr, "Done: dialog execute exited:%d\n", result);
    return result;
}

#undef Dialog
short RunDialog( ::Dialog& dialog )
{
    dialog.Show();
    short result = dialog.Execute();
    fprintf( stderr, "Done: dialog execute exited:%d\n", result);
    return result;
}

#if SORT_DLG
static void LoadSC()
{
    get_factory( "com.sun.star.comp.sfx2.DocumentTemplates" );
    get_factory( "com.sun.star.comp.Calc.SpreadsheetDocument" );
    GET_FACTORY( com.sun.star.i18n.Transliteration.l10n );
}
#endif /* SORT_DLG */

void TestDialog( OUString const& name )
{
    if ( 0 )
        ;
    else if ( name.equalsAscii( "plugin" ) )
    {
        PluginDialog plugin ( 0 );
        RunDialog( plugin );
    }
    else if ( name.equalsAscii( "query" ) )
    {
        QueryBox query ( 0, "Do you want to do?", "do");
        RunDialog( query );
    }
    else if ( name.equalsAscii( "query-compat" ) )
    {
        QueryBox query ( 0,
                         WinBits( WB_YES_NO | WB_DEF_YES ),
//                         WinBits( WB_ABORT_RETRY_IGNORE ),
                         OUString::createFromAscii ("Do you want to do?"));
        RunDialog( query );
    }
    else if ( name.equalsAscii( "recover" ) )
    {
        SvxRecoverDialog recover ( 0 );
        RunDialog( recover );
    }
#if SORT_DLG
    else if ( name.equalsAscii( "sort" ) )
    {
        LoadSC();
        ScSortDlg sort (0, 0);
        RunDialog( sort );
    }
#endif /* SORT_DLG */
    else if ( name.equalsAscii( "wordcount" ) )
    {
        SwWordCountDialog words ( 0 );
        RunDialog( words );
    }
    else if ( name.equalsAscii( "zoom" ) )
    {
        SvxZoomDialog zoom( 0 );
        RunDialog( zoom );
    }
}

void LayoutTest::RunFiles()
{
    fprintf( stderr, "TEST: loading files\n" );
    for ( std::list< OUString >::iterator  i = mFiles.begin(); i != mFiles.end(); i++ )
        LoadFile( *i );
    fprintf( stderr, "TEST: executing\n" );
    Execute();
    fprintf( stderr, "TEST: done executing\n" );
}

void LayoutTest::ExceptionalMain()
{
    if ( mTestDialog.getLength() )
        TestDialog( mTestDialog );
    else if ( mEditMode )
        RunEditor();
    else
        RunFiles();
}

void LayoutTest::Main()
{
    try
    {
        ExceptionalMain();
    }
    catch (xml::sax::SAXException & rExc)
    {
        OString aStr( OUStringToOString( rExc.Message,
                                         RTL_TEXTENCODING_ASCII_US ) );
        uno::Exception exc;
        if (rExc.WrappedException >>= exc)
        {
            aStr += OString( " >>> " );
            aStr += OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US );
        }
        fprintf (stderr, "Parsing error: '%s'\n", aStr.getStr());
        OSL_ENSURE( 0, aStr.getStr() );
    }
    catch ( uno::Exception & rExc )
    {
        OString aStr( OUStringToOString( rExc.Message,
                                         RTL_TEXTENCODING_ASCII_US ) );
        fprintf (stderr, "UNO error: '%s'\n", aStr.getStr());
        OSL_ENSURE( 0, aStr.getStr() );
    }

    Reference< lang::XComponent > xComp( mxContext, UNO_QUERY );
    if ( xComp.is() )
        xComp->dispose();
}

LayoutTest::LayoutTest( char const* installDir )
    : mInstallDir( OUString::createFromAscii ( installDir ) )
{
}

LayoutTest layout_test( "/usr/local/lib/ooo" );
