//
// Example application level use of Flatbuffers with WAMP.
//

include "zlmdb.fbs";

/// Our accelerometer example API lives in this namespace.
namespace demo.accelstorage;


/// One sample from accelerometer sensor.
struct AccelSample
{
    x: float;
    y: float;
    z: float;
}


/// A series of samples from the accelerometer sensor.
table AccelSeries
{
    /// Unix epoch when sample batch was recorded (start thereof).
    sample_start: uint64;

    /// Sample length in ms.
    sample_period: uint16;

    /// Sample batch with accelerometer readings.
    samples: [AccelSample];
}


/// A time range.
table TimeRange
{
    foo: uint8;
    /// Unix epoch start time or 0 for infinity into the past.
    start: uint32 (uuid);

    /// Unix epoch end time or 0 for infinity into the future.
    endof: uint64 (uuid: "81d3403a-8203-47a6-b7bd-dbaae03195b7");

    bar: uint8 (uuid: 1, uuid: 2, uuid: 3);
}


/// A batch of sample series.
table AccelBatch
{
    series: [AccelSeries];
    test: int;
}


/// Error raised when the accelerometer data supplied was invalid.
/// The error provides details about the deviation detected.
table AccelSeriesRejected (type: "error")
{
    /// In case the error was raised because of outliers,
    /// the probability of detection
    outlier_probability: float;

    /// Number of outlier samples (individual readings) detected.
    outlier_cout: uint32;
}


/// No sample series matching the criteria could be found.
table NoSuchSeries
{
}


/// Define an interface for accelerometer storage services.
rpc_service AccelStorage (type: "interface",
                          uuid: "4b740947-31d5-4a10-b7ce-4149bbc9ee1e")
{
    //
    // Examples of basic WAMP RPC and PubSub interface declarations
    //

    /// Procedure to store a series of samples. The time range of
    /// samples stored is returned.
    store (AccelSeries): TimeRange (type: "procedure", raises: "AccelSeriesRejected");

    /// Procedure that returns the last series of samples stored
    // within the given time range.
    get_last (TimeRange): AccelSeries (type: "procedure", raises: "NoSuchSeries");

    /// Event fired when a sample batch was stored. The time range
    /// of the stored samples is provided as event payload.
    on_store (TimeRange): Void (type: "topic");
}


/// Define an interface for accelerometer storage services.
rpc_service AccelStorageAdvanced (type: "interface",
                                  uuid: "14dd174c-efc0-4ebb-9bb5-3e59379e7b26")
{
    //
    // Examples of **streaming return and/or argument** WAMP procedure declarations
    //

    /// Fetch all sample series within the given time range as one batch.
    fetch_batch (TimeRange): AccelBatch (type: "procedure");

    /// Fetch all sample series within the given time range.
    /// Sample series are returned as streaming, "progressive results".
    fetch_stream (TimeRange): AccelSeries (type: "procedure", stream: "out");

    /// Bulk upload sample batches.
    store_batch (AccelBatch): TimeRange (type: "procedure");

    /// Bulk upload sample batches.
    /// Sample batches are provided as streaming, "progressive call arguments"
    store_stream (AccelSeries): TimeRange (type: "procedure", stream: "in");

    /// Compute sliding window average of sample using bulk transformation
    /// of batches of samples.
    average_batch (AccelBatch): AccelBatch (type: "procedure");

    /// Compute sliding window average of sample using a streaming transformation
    /// receiving arguments and producing results in a full duplex stream.
    average_stream (AccelSeries): AccelSeries (type: "procedure", stream: "inout");
}


/// Our survey example API lives in this namespace.
namespace demo.survey;

enum Moo: uint8
{
    TEST,
    TESDT2
}

/// Gender (simplified;).
enum Gender: uint8 (uuid: "TEST 666")
{
    /// Unset or unknown gender.
    UNSET = 0,

    /// Gender is male.
    MALE = 1,

    /// Gender is female.
    FEMALE = 2,
}


/// Ice cream surveys.
table IceCreamOfTheDaySurvey (uuid: "TEST 2323")
{
    /// Unix epoch (UTC) when survey expires.
    expires: uint64 (uuid: "TEST 4242");
    moo: Moo;

    test_1: accelstorage.AccelSample;

    test_2: accelstorage.TimeRange;
}


/// Replies to ice cream surveys.
table IceCreamOfTheDayReply
{
    /// Your age in years.
    age: uint16;

    /// Your gender.
    gender: Gender = FEMALE;

    /// SHA256 of your email address.
    hashed_email: [uint8];

    /// Survey flag: you like lemon ice cream?
    likes_lemon: bool;

    /// Survey flag: you like strawberry ice cream?
    likes_strawberry: bool;

    /// Survey flag: you like chocolate ice cream?
    likes_chocolate: bool;
}


/// Ice cream survey services may implement this awesome interface;)
rpc_service IceCreamSurvey (type: "interface",
                            uuid: "7e2c99b7-7506-477f-b782-7266a9e76126")
{
    //
    // Examples of **event receiver replies** WAMP topic declarations
    //

    /// Ice cream surveys are published as events on this topic.
    /// When a receiver of the event decides to take part in the survey,
    /// the receiver returns a `IceCreamOfTheDayReply` result (instead of
    /// returning nothing, as usually in an event handler).
    on_new_survey (IceCreamOfTheDaySurvey): IceCreamOfTheDayReply (type: "topic");
}
