/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */

#include <com/sun/star/lang/IllegalArgumentException.idl>
#include <com/sun/star/lang/XComponent.idl>
#include <com/sun/star/uno/XComponentContext.idl>
#include <com/sun/star/uno/XInterface.idl>

module test { module testtools { module bridgetest {

enum TestEnum
{
    TEST,
    ONE,
    TWO,
    CHECK,
    LOLA,
    PALOO,
    ZA
};

enum TestBadEnum { M = 1 };

struct TestStruct
{
    long member;
};

/**
 * simple types
 */
struct TestSimple
{
    boolean                    Bool;
    char                       Char;
    byte                       Byte;
    short                      Short;
    unsigned short             UShort;
    long                       Long;
    unsigned long              ULong;
    hyper                      Hyper;
    unsigned hyper             UHyper;
    float                      Float;
    double                     Double;
    TestEnum                   Enum;
};
/**
 * equal to max size returned in registers on x86_64
 */
struct SmallStruct
{
    hyper                      a;
    hyper                      b;
};
/**
 * equal to max size returned in registers on ia64
 */
struct MediumStruct
{
    hyper                      a;
    hyper                      b;
    hyper                      c;
    hyper                      d;
};
/**
 * bigger than max size returned in registers on ia64
 */
struct BigStruct
{
    hyper                      a;
    hyper                      b;
    hyper                      c;
    hyper                      d;
    hyper                      e;
    hyper                      f;
    hyper                      g;
    hyper                      h;
};
/**
 * two floats, BSDs/MacOSX on intel handle returning small
 * structs differently than Linux
 */
struct TwoFloats
{
    float                      a;
    float                      b;
};
/**
 * all floats, ia64 handles them specially
 */
struct FourFloats
{
    float                      a;
    float                      b;
    float                      c;
    float                      d;
};
/**
 * Small struct with mixed float and integers.
 * Should return in registers on BSDs/MACOSx
 */
struct MixedFloatAndInteger
{
    float                      a;
    long                       b;
};
/**
 * Small struct with three bytes.  Should *not* return in registers on
 * BSDs/MACOSx
 */
struct ThreeByteStruct
{
    byte                       a;
    byte                       b;
    byte                       c;
};
/**
 * complex types adding string, interface, any
 */
struct TestElement : TestSimple
{
    string                     String;
    com::sun::star::uno::XInterface   Interface;
    any                        Any;
};
/**
 * adding even more complexity, sequence< TestElement >
 */
struct TestDataElements : TestElement
{
    sequence< TestElement > Sequence;
};

/**
 * typedef used in interface
 */
typedef TestDataElements TestData;

struct TestPolyStruct<T> { T member; };
struct TestPolyStruct2<T,C> {
    T member1;
    C member2;
};

interface XRecursiveCall : com::sun::star::uno::XInterface
{
    /***
     * @param nToCall If nToCall is 0, the method returns immediately.
     *                Otherwise, call the given interface with nToCall -1
     *
     ***/
    void callRecursivly( [in] XRecursiveCall xCall , [in] long nToCall );
};

interface XMultiBase1 {
    [attribute] double att1; // initially 0.0
    long fn11([in] long arg); // return 11 * arg
    string fn12([in] string arg); // return "12" + arg
};

interface XMultiBase2: XMultiBase1 {
    long fn21([in] long arg); // return 21 * arg
    string fn22([in] string arg); // return "22" + arg
};

interface XMultiBase3 {
    [attribute] double att3; // initially 0.0
    long fn31([in] long arg); // return 31 * arg
    string fn32([in] string arg); // return "32" + arg
    long fn33(); // return 33
};

interface XMultiBase3a: XMultiBase3 {};

interface XMultiBase4 {
    long fn41([in] long arg); // return 41 * arg
};

interface XMultiBase5 {
    interface XMultiBase3;
    interface XMultiBase4;
    interface XMultiBase1;
};

interface XMultiBase6 {
    interface XMultiBase2;
    interface XMultiBase3a;
    interface XMultiBase5;
    long fn61([in] long arg); // return 61 * arg
    string fn62([in] string arg); // return "62" + arg
};

interface XMultiBase7 {
    long fn71([in] long arg); // return 71 * arg
    string fn72([in] string arg); // return "72" + arg
    long fn73(); // return 73
};

interface XMulti {
    interface XMultiBase6;
    interface XMultiBase7;
};

/**
 * Monster test interface to test bridge calls.
 * An implementation of this object has to store given values and return whenever there
 * is an out param or return value.
 */
interface XBridgeTestBase : com::sun::star::uno::XInterface
{
    /**
     * in parameter test, tests by calls reference also (complex types)
     */
    void setValues( [in] boolean bBool, [in] char cChar, [in] byte nByte,
                             [in] short nShort, [in] unsigned short nUShort,
                             [in] long nLong, [in] unsigned long nULong,
                             [in] hyper nHyper, [in] unsigned hyper nUHyper,
                             [in] float fFloat, [in] double fDouble,
                             [in] TestEnum eEnum, [in] string aString,
                             [in] com::sun::star::uno::XInterface xInterface, [in] any aAny,
                             [in] sequence< TestElement > aSequence,
                             [in] TestData aStruct );
    /**
     * inout parameter test
     *
     * @return aStruct. The out parameter contain the values, that were previously set
     *         by setValues or (if not called before) default constructed values.
     *
     */
    TestData setValues2( [inout] boolean bBool, [inout] char cChar, [inout] byte nByte,
                         [inout] short nShort, [inout] unsigned short nUShort,
                         [inout] long nLong, [inout] unsigned long nULong,
                         [inout] hyper nHyper, [inout] unsigned hyper nUHyper,
                         [inout] float fFloat, [inout] double fDouble,
                         [inout] TestEnum eEnum, [inout] string aString,
                         [inout] com::sun::star::uno::XInterface xInterface, [inout] any aAny,
                         [inout] sequence< TestElement > aSequence,
                         [inout] TestData aStruct );

    /**
     * out parameter test
     */
    TestData getValues( [out] boolean bBool, [out] char cChar, [out] byte nByte,
                        [out] short nShort, [out] unsigned short nUShort,
                        [out] long nLong, [out] unsigned long nULong,
                        [out] hyper nHyper, [out] unsigned hyper nUHyper,
                        [out] float fFloat, [out] double fDouble,
                        [out] TestEnum eEnum, [out] string aString,
                        [out] com::sun::star::uno::XInterface xInterface, [out] any aAny,
                        [out] sequence< TestElement > aSequence,
                        [out] TestData aStruct );

    /**
     * register return test 1
     */
    SmallStruct echoSmallStruct( [in] SmallStruct aStruct );

    /**
     * register return test 2
     */
    MediumStruct echoMediumStruct( [in] MediumStruct aStruct );

    /**
     * register return test 3
     */
    BigStruct echoBigStruct( [in] BigStruct aStruct );

    /**
     * register return test 4
     */
    TwoFloats echoTwoFloats( [in] TwoFloats aStruct );

    /**
     * register return test 5
     */
    FourFloats echoFourFloats( [in] FourFloats aStruct );

    /**
     * register return test 6
     */
    MixedFloatAndInteger echoMixedFloatAndInteger( [in] MixedFloatAndInteger aStruct );

    /**
     * register return test 7
     */
    ThreeByteStruct echoThreeByteStruct( [in] ThreeByteStruct aStruct );

    /**
     * PPC Alignment test (#i107182#)
     */
    long testPPCAlignment( [in] hyper l1, [in] hyper l2, [in] long i1, [in] hyper l3, [in] long i2 );

    /**
     * PPC64 Alignment test
     */
    long testPPC64Alignment( [in] double d1, [in] double d2, [in] double d3, [in] long i1 );


    /**
     * VFP ABI (armhf) doubles test
     */
    double testTenDoubles( [in] double d1, [in] double d2, [in] double d3, [in] double d4, [in] double d5, [in] double d6, [in] double d7, [in] double d8, [in] double d9, [in] double d10 );

    [attribute] boolean                  Bool;
    [attribute] byte                     Byte;
    [attribute] char                     Char;
    [attribute] short                    Short;
    [attribute] unsigned short           UShort;
    [attribute] long                     Long;
    [attribute] unsigned long            ULong;
    [attribute] hyper                    Hyper;
    [attribute] unsigned hyper           UHyper;
    [attribute] float                    Float;
    [attribute] double                   Double;
    [attribute] TestEnum                 Enum;
    [attribute] string                   String;
    [attribute] com::sun::star::uno::XInterface Interface;
    [attribute] any                      Any;
    [attribute] sequence< TestElement >  Sequence;
    [attribute] TestData                 Struct;

    [attribute] long RaiseAttr1 {
        set raises (com::sun::star::lang::IllegalArgumentException);
    };
    [attribute, readonly] long RaiseAttr2 {
        get raises (com::sun::star::lang::IllegalArgumentException);
    };

    TestPolyStruct<boolean> transportPolyBoolean(
        [in] TestPolyStruct<boolean> arg);
    void transportPolyHyper([inout] TestPolyStruct<hyper> arg);
    void transportPolySequence(
        [in] TestPolyStruct<sequence<any> > arg1,
        [out] TestPolyStruct<sequence<any> > arg2);

    TestPolyStruct<long> getNullPolyLong();
    TestPolyStruct<string> getNullPolyString();
    TestPolyStruct<type> getNullPolyType();
    TestPolyStruct<any> getNullPolyAny();
    TestPolyStruct<sequence<boolean> > getNullPolySequence();
    TestPolyStruct<TestEnum> getNullPolyEnum();
    TestPolyStruct<TestBadEnum> getNullPolyBadEnum();
    TestPolyStruct<TestStruct> getNullPolyStruct();
    TestPolyStruct<XBridgeTestBase> getNullPolyInterface();

    /***
     * This method returns the parameter value.
     * Method to extensivly test anys.
     ****/
    any transportAny( [in] any value );

    /***
     * methods to check sequence of calls. Call call() and callOneway
     * in an arbitrary sequence. Increase the callId for every call.
     * The testobject sets an error flag.

        @see testSequencePassed
     ***/
    void call( [in] long nCallId, [in] long nWaitMUSEC );
    void callOneway( [in] long nCallId, [in] long nWaitMUSEC );
    boolean sequenceOfCallTestPassed();

    /****
     * methods to check, if threads thread identity is holded.
     *
     ***/
    void startRecursiveCall( [in] XRecursiveCall xCall , [in] long nToCall );

    XMulti getMulti();
    string testMulti([in] XMulti multi);
};


/**
 * Inherting from monster; adds raiseException(), attribute raising RuntimeException.
 */
interface XBridgeTest : XBridgeTestBase
{
    /**
     * the exception struct returned has to be filled with given arguments.
     * return value is for dummy.
     */
    TestData raiseException( [in] short ArgumentPosition,
                             [in] string Message,
                             [in] com::sun::star::uno::XInterface Context )
        raises( com::sun::star::lang::IllegalArgumentException );


    /**
     * Throws runtime exception.
     * check remote bridges handle exceptions during oneway calls properly.
     * Note that on client side the exception may fly or not. When it flies, it should
     * have the proper message and context.
     ***/
    void raiseRuntimeExceptionOneway(  [in] string Message,
                                       [in] com::sun::star::uno::XInterface Context );

    /**
     * raises runtime exception;
     * the exception struct returned has to be filled with formerly set test data.
     */
    [attribute] long                     RuntimeException;
};


exception BadConstructorArguments: com::sun::star::uno::Exception {};

service Constructors: com::sun::star::uno::XInterface {
    create1(
        [in] boolean arg0,
        [in] byte arg1,
        [in] short arg2,
        [in] unsigned short arg3,
        [in] long arg4,
        [in] unsigned long arg5,
        [in] hyper arg6,
        [in] unsigned hyper arg7,
        [in] float arg8,
        [in] double arg9,
        [in] char arg10,
        [in] string arg11,
        [in] type arg12,
        [in] any arg13,
        [in] sequence< boolean > arg14,
        [in] sequence< byte > arg15,
        [in] sequence< short > arg16,
        [in] sequence< unsigned short > arg17,
        [in] sequence< long > arg18,
        [in] sequence< unsigned long > arg19,
        [in] sequence< hyper > arg20,
        [in] sequence< unsigned hyper > arg21,
        [in] sequence< float > arg22,
        [in] sequence< double > arg23,
        [in] sequence< char > arg24,
        [in] sequence< string > arg25,
        [in] sequence< type > arg26,
        [in] sequence< any > arg27,
        [in] sequence< sequence< boolean > > arg28,
        [in] sequence< sequence< any > > arg29,
        [in] sequence< TestEnum > arg30,
        [in] sequence< TestStruct > arg31,
        [in] sequence< TestPolyStruct< boolean > > arg32,
        [in] sequence< TestPolyStruct< any > > arg33,
        [in] sequence< com::sun::star::uno::XInterface > arg34,
        [in] TestEnum arg35,
        [in] TestStruct arg36,
        [in] TestPolyStruct< boolean > arg37,
        [in] TestPolyStruct< any > arg38,
        [in] com::sun::star::uno::XInterface arg39)
        raises (BadConstructorArguments);

    create2([in] any... args) raises (BadConstructorArguments);

};

service Constructors2: XMultiBase1 {

    create1(
        [in] TestPolyStruct<type> arg1,
        [in] TestPolyStruct<any> arg2,
        [in] TestPolyStruct<boolean> arg3,
        [in] TestPolyStruct<byte> arg4,
        [in] TestPolyStruct<short> arg5,
        [in] TestPolyStruct<long> arg6,
        [in] TestPolyStruct<hyper> arg7,
        [in] TestPolyStruct<char> arg8,
        [in] TestPolyStruct<string> arg9,
        [in] TestPolyStruct<float> arg10,
        [in] TestPolyStruct<double> arg11,
        [in] TestPolyStruct<com::sun::star::uno::XInterface> arg12,
        [in] TestPolyStruct<com::sun::star::lang::XComponent> arg13,
        [in] TestPolyStruct<TestEnum> arg14,
        [in] TestPolyStruct<TestPolyStruct2<char,any> > arg15,
        [in] TestPolyStruct<TestPolyStruct2<TestPolyStruct2<char,any>,string> > arg16,
        [in] TestPolyStruct2<string, TestPolyStruct2<char, TestPolyStruct<any> > > arg17,
        [in] TestPolyStruct2<TestPolyStruct2<char,any>, TestPolyStruct<char> > arg18,
        [in] TestPolyStruct<sequence<type> > arg19,
        [in] TestPolyStruct<sequence<any> > arg20,
        [in] TestPolyStruct<sequence<boolean> > arg21,
        [in] TestPolyStruct<sequence<byte> > arg22,
        [in] TestPolyStruct<sequence<short> > arg23,
        [in] TestPolyStruct<sequence<long> > arg24,
        [in] TestPolyStruct<sequence<hyper> > arg25,
        [in] TestPolyStruct<sequence<char> > arg26,
        [in] TestPolyStruct<sequence<string> > arg27,
        [in] TestPolyStruct<sequence<float> > arg28,
        [in] TestPolyStruct<sequence<double> > arg29,
        [in] TestPolyStruct<sequence<com::sun::star::uno::XInterface> > arg30,
        [in] TestPolyStruct<sequence<com::sun::star::lang::XComponent> > arg31,
        [in] TestPolyStruct<sequence<TestEnum> > arg32,
        [in] TestPolyStruct<sequence<TestPolyStruct2<char, sequence<any> > > > arg33,
        [in] TestPolyStruct<sequence<TestPolyStruct2<TestPolyStruct<char>, sequence<any> > > > arg34,
        [in] TestPolyStruct<sequence<sequence<long> > > arg35,
        [in] sequence<TestPolyStruct<long > > arg36,
        [in] sequence<TestPolyStruct<TestPolyStruct2<char,any> > > arg37,
        [in] sequence<TestPolyStruct<TestPolyStruct2<TestPolyStruct2<char,any>,string> > > arg38,
        [in] sequence<TestPolyStruct2<string, TestPolyStruct2<char, TestPolyStruct<any> > > > arg39,
        [in] sequence<TestPolyStruct2<TestPolyStruct2<char,any>, TestPolyStruct<char> > > arg40,
        [in] sequence<sequence<TestPolyStruct< char > > > arg41,
        [in] sequence<sequence<TestPolyStruct<TestPolyStruct2<char,any> > > >arg42,
        [in] sequence<sequence<TestPolyStruct<TestPolyStruct2<TestPolyStruct2<char,any>,string> > > > arg43,
        [in] sequence<sequence<TestPolyStruct2<string, TestPolyStruct2<char, TestPolyStruct<any> > > > > arg44,
        [in] sequence<sequence<TestPolyStruct2<TestPolyStruct2<char,any>, TestPolyStruct<char> > > > arg45
        );
};

interface XCurrentContextChecker {
    boolean perform(
        [in] XCurrentContextChecker other, [in] long setSteps,
        [in] long checkSteps);
};

/** Extended tests with sequences.
 */
interface XBridgeTest2 : XBridgeTest
{
    sequence< boolean > setSequenceBool( [in] sequence< boolean > aSeq);
    sequence< char > setSequenceChar( [in] sequence< char > aSeq);
    sequence< byte> setSequenceByte( [in] sequence< byte > aSeq);
    sequence< short> setSequenceShort( [in] sequence< short > aSeq);
    sequence< unsigned short > setSequenceUShort( [in] sequence< unsigned short > aSeq);
    sequence< long > setSequenceLong( [in] sequence< long > aSeq);
    sequence< unsigned long > setSequenceULong( [in] sequence< unsigned long > aSeq);
    sequence< hyper > setSequenceHyper( [in] sequence< hyper > aSeq);
    sequence< unsigned hyper > setSequenceUHyper( [in] sequence< unsigned hyper > aSeq);
    sequence< float > setSequenceFloat( [in] sequence< float > aSeq);
    sequence< double > setSequenceDouble( [in] sequence< double > aSeq);
    sequence< TestEnum > setSequenceEnum( [in] sequence< TestEnum > aSeq);
    sequence< string > setSequenceString( [in] sequence< string > aString);
    sequence< com::sun::star::uno::XInterface > setSequenceXInterface(
        [in] sequence< com::sun::star::uno::XInterface > aSeq);
    sequence< any > setSequenceAny( [in] sequence< any > aSeq);
    sequence< TestElement > setSequenceStruct( [in] sequence< TestElement > aSeq);

    sequence< sequence< long > > setDim2( [in] sequence< sequence< long > > aSeq);
    sequence< sequence < sequence < long > > > setDim3(
        [in] sequence< sequence < sequence < long > > > aSeq);

    void setSequencesInOut( [inout] sequence< boolean > aSeqBoolean,
                       [inout] sequence< char > aSeqChar,
                       [inout] sequence< byte > aSeqByte,
                       [inout] sequence< short > aSeqShort,
                       [inout] sequence< unsigned short> aSeqUShort,
                       [inout] sequence< long > aSeqLong,
                       [inout] sequence< unsigned long > aSeqULong,
                       [inout] sequence< hyper > aSeqHyper,
                       [inout] sequence< unsigned hyper > aSeqUHyper,
                       [inout] sequence< float > aSeqFloat,
                       [inout] sequence< double > aSeqDouble,
                       [inout] sequence< TestEnum > aSeqEnum,
                       [inout] sequence< string > aSeqString,
                       [inout] sequence< com::sun::star::uno::XInterface > aSeqXInterface,
                       [inout] sequence< any > aSeqAny,
                       [inout] sequence< sequence< long > > aSeqDim2,
                       [inout] sequence< sequence < sequence < long > > > aSeqDim3);

    void setSequencesOut( [out] sequence< boolean > aSeqBoolean,
                       [out] sequence< char > aSeqChar,
                       [out] sequence< byte > aSeqByte,
                       [out] sequence< short > aSeqShort,
                       [out] sequence< unsigned short> aSeqUShort,
                       [out] sequence< long > aSeqLong,
                       [out] sequence< unsigned long > aSeqULong,
                       [out] sequence< hyper > aSeqHyper,
                       [out] sequence< unsigned hyper > aSeqUHyper,
                       [out] sequence< float > aSeqFloat,
                       [out] sequence< double > aSeqDouble,
                       [out] sequence< TestEnum > aSeqEnum,
                       [out] sequence< string > aSeqString,
                       [out] sequence< com::sun::star::uno::XInterface > aSeqXInterface,
                       [out] sequence< any > aSeqAny,
                       [out] sequence< sequence< long > > aSeqDim2,
                       [out] sequence< sequence < sequence < long > > > aSeqDim3);

    void testConstructorsService(
        [in] com::sun::star::uno::XComponentContext context)
        raises (BadConstructorArguments);

    XCurrentContextChecker getCurrentContextChecker();
};

}; }; };

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
