// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.controller.test;

using zx;

type EmptyUnion = flexible union {};

type NoopUnion = flexible union {
    1: union_str string:255;
    2: union_bool bool;
    3: union_int int64;
};

type SomeBits = strict bits : uint64 {
    FOO = 0x8000000000000000;
};

type NoopTable = table {
    1: dub float32;
    2: str string:255;
    3: union_field NoopUnion;
    4: integer int64;
};

@discoverable
closed protocol Noop {
    strict DoStringNoop(struct {
        value string:255;
    }) -> ();

    strict DoIntNoop(struct {
        value int32;
    }) -> ();

    strict DoTableNoop(struct {
        tab NoopTable;
    }) -> ();

    strict StrictOneWayUnion(flexible union {
        1: value int32;
        2: other_value string:10;
    });

    strict StrictTwoWayUnion(flexible union {
        1: value int32;
        2: other_value string:10;
    }) -> ();

    strict DoHandleNoop(resource struct {
        server_end zx.Handle:CHANNEL;
    }) -> ();

    strict DoVectorNoop(struct {
        v vector<string:255>:255;
    }) -> ();

    strict DoArrayNoop(struct {
        a array<int32, 4>;
    }) -> ();

    strict DoBitsNoop(struct {
        b SomeBits;
    }) -> ();

    strict DoNoop() -> ();
};

@discoverable
open protocol ComposerThing {
    strict ReturnPossibleError() -> (struct {
        some_bool_value bool;
    }) error zx.Status;

    flexible ReturnPossibleError2() -> () error zx.Status;
};

open protocol OtherComposedProtocol {
    compose ComposerThing;
};

@discoverable
open protocol Testing {
    compose ComposerThing;

    strict ReturnUnion() -> (flexible union {
        1: x uint8;
        2: y string:255;
    });

    strict ReturnUnionWithTable() -> (flexible union {
        1: x NoopUnion;
        2: y NoopTable;
    });

    strict ReturnOtherComposedProtocol() -> (resource struct {
        client_thing client_end:OtherComposedProtocol;
    });

    strict ReturnSocketOrError() -> (resource struct {
        reader_thing zx.Handle:SOCKET;
    }) error zx.Status;
};

@discoverable
closed protocol ExampleEvents {
    strict -> OnFirst(struct {
        message string:128;
    });

    strict -> OnSecond();
};

open protocol FlexibleMethodTester {
    flexible SomeMethod() -> (struct {
        some_bool_value bool;
    }) error zx.Status;

    flexible SomeMethodWithoutError() -> (struct {
        some_bool_value bool;
    });

    flexible SomeMethodJustError() -> () error zx.Status;

    flexible FlexibleOneWayUnion(flexible union {
        1: value int32;
        2: other_value string:10;
    });

    flexible FlexibleTwoWayUnion(flexible union {
        1: value int32;
        2: other_value string:10;
    }) -> ();
};

alias AliasOfArray = array<int16, 3>;
