/*
 * 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;

import IBase;
import IBazCallback;

interface IBaz extends IBase {

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

    struct BitFieldTester {
      bitfield<BitField> scalar;
      vec<bitfield<BitField>> vector;
     };

    enum SomeOtherEnum : uint8_t {
        bar = 66
    };

    typedef SomeOtherEnum thisIsAnAlias;
    typedef IBaz anIBazByAnyOtherName;

    struct NastyNester {
        struct NestersNasty {
            struct NestersNastyNester {
                IBaz baz;
                vec<NestersNasty> nasties;
            };
        };

        IBaz baz;
    };

    enum SomeEnum : SomeOtherEnum {
        quux = 33,
        goober = 192,
        blah = goober
    };

    typedef int32_t[3] ThreeInts;
    struct T {
        ThreeInts[5]  matrix5x3;
        int32_t[3][5] matrix3x5;
    };

    struct NestedStruct {
        int32_t a;
        vec<T> matrices;
    };

    struct Quux {
        string first;
        string last;
    };
    struct Everything {
        int8_t number;
        int32_t anotherNumber;
        string s;
        vec<string> vs;
        string[2][2] multidimArray;
        string[3] sArray;
        Quux anotherStruct;
        bitfield<BitField> bf;
    };

    struct MyHandle {
        handle h;
        int32_t guard;
    };

    struct StructWithInterface {
        int32_t number;
        int8_t[7] array;
        string oneString;
        vec<string> vectorOfStrings;
        interface iface;
    };
    oneway doThis(float param);

    doThatAndReturnSomething(int64_t param) generates (int32_t result);
    doQuiteABit(int32_t a, int64_t b, float c, double d) generates (double something);
    doSomethingElse(int32_t[15] param) generates (int32_t[32] something);
    doStuffAndReturnAString() generates (string something);
    mapThisVector(vec<int32_t> param) generates (vec<int32_t> something);
    callMe(IBazCallback cb);

    callMeLater(IBazCallback cb);
    iAmFreeNow();
    dieNow();

    useAnEnum(SomeEnum zzz) generates (SomeEnum kkk);

    haveSomeStrings(string[3] array) generates (string[2] result);
    haveAStringVec(vec<string> vector) generates (vec<string> result);
    repeatBitfieldVec(vec<bitfield<BitField>> vector) generates (vec<bitfield<BitField>> result);

    returnABunchOfStrings() generates (string a, string b, string c);

    returnABitField() generates (bitfield<BitField> good);

    size(uint32_t size) generates (uint32_t size);

    getNestedStructs() generates(vec<NestedStruct> data);

    haveSomeStructWithInterface(StructWithInterface swi) generates(StructWithInterface swi);
};
