/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed 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.
 */

package android.hardware.tests.baz@1.0;

interface IBase {
    enum SomeBaseEnum : int32_t {
        grrr = 1,
    };

    struct Foo {
        struct Bar {
            float z;
            string s;
        };

        enum FooEnum : int8_t {
            first = 1,
            second = 2,
        };

        int32_t x;
        vec<Bar> aaa;
        Bar y;
    };

    struct MoreThanOneArrayField {
        /**
         * Generated (Java) code used to redeclare the same variable name
         * multiple times in the same scope, this test ensures that that's no
         * longer the case.
         */
        string[3] one;
        string[5] two;
    };

    typedef string[3] ThreeStrings;
    typedef string[5] FiveStrings;

    struct StringMatrix3x5 {
        FiveStrings[3] s;
    };

    struct StringMatrix5x3 {
        ThreeStrings[5] s;
    };

    typedef uint8_t[6] MacAddress;

    struct VectorOfArray {
        vec<MacAddress> addresses;
    };

    enum BitField : uint8_t {
        V0 = 1 << 0,
        V1 = 1 << 1,
        V2 = 1 << 2,
        V3 = 1 << 3,
    };

    struct MyMask {
        bitfield<BitField> value;
    };

    typedef bitfield<BitField> Mask;

    typedef uint8_t[128] ByteOneDim;
    typedef uint8_t[8][128] ByteTwoDim;
    typedef uint8_t[8][16][128] ByteThreeDim;

    typedef bool[128] BooleanOneDim;
    typedef bool[8][128] BooleanTwoDim;
    typedef bool[8][16][128] BooleanThreeDim;

    typedef double[128] DoubleOneDim;
    typedef double[8][128] DoubleTwoDim;
    typedef double[8][16][128] DoubleThreeDim;

    struct LotsOfPrimitiveArrays {
        ByteOneDim byte1;
        ByteTwoDim byte2;
        ByteThreeDim byte3;
        BooleanOneDim boolean1;
        BooleanTwoDim boolean2;
        BooleanThreeDim boolean3;
        DoubleOneDim double1;
        DoubleTwoDim double2;
        DoubleThreeDim double3;
    };

    isJava() generates (bool isJava);

    someBaseMethod();

    someBoolMethod(bool x) generates (bool y);
    someBoolArrayMethod(bool[3] x) generates (bool[4] y);
    someBoolVectorMethod(vec<bool> x) generates (vec<bool> y);

    someOtherBaseMethod(Foo foo) generates (Foo result);
    someMethodWithFooArrays(Foo[2] fooInput) generates (Foo[2] fooOutput);
    someMethodWithFooVectors(vec<Foo> fooInput) generates (vec<Foo> fooOutput);

    someMethodWithVectorOfArray(VectorOfArray in) generates (VectorOfArray out);

    someMethodTakingAVectorOfArray(vec<MacAddress> in)
        generates (vec<MacAddress> out);

    transpose(StringMatrix5x3 in) generates (StringMatrix3x5 out);
    transpose2(ThreeStrings[5] in) generates (FiveStrings[3] out);

    takeAMask(BitField bf, bitfield<BitField> first, MyMask second, Mask third)
            generates (BitField out, uint8_t f, uint8_t s, uint8_t t);

    testArrays(LotsOfPrimitiveArrays in) generates (LotsOfPrimitiveArrays out);
    testByteVecs(vec<ByteOneDim> in) generates (vec<ByteOneDim> out);
    testBooleanVecs(vec<BooleanOneDim> in) generates (vec<BooleanOneDim> out);
    testDoubleVecs(vec<DoubleOneDim> in) generates (vec<DoubleOneDim> out);
};
