// Copyright 2020 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.examples.docs;

using zx;

// [START structs]
type CirclePoint = struct {
    x float32;
    y float32;
};

type Color = struct {
    r float32;
    g float32;
    b float32;
};
// [END structs]

// [START structs-use]
type Circle = struct {
    filled bool;
    center CirclePoint; // CirclePoint will be stored in-line
    radius float32;
    color box<Color>; // Color will be stored out-of-line
    dashed bool;
};
// [END structs-use]

// [START comments]
// this is a comment
/// and this one is too, but it also ends up in the generated code
type MyStruct = struct { // plain comment
    f int32; // as is this one
}; // and this is the last one!
// [END comments]

// [START consts]
const ENABLED_FLAG bool = true;
const OFFSET int8 = -33;
const ANSWER uint16 = 42;
const ANSWER_IN_BINARY uint16 = 0b101010;
const POPULATION_USA_2018 uint32 = 330000000;
const DIAMOND uint64 = 0x183c7effff7e3c18;
const FUCHSIA uint64 = 4054509061583223046;
const USERNAME string = "squeenze";
const MIN_TEMP float32 = -273.15;
const CONVERSION_FACTOR float64 = 1.41421358;
const MY_DRINK Beverage = Beverage.WATER;
// [END consts]

// [START defaults]
type Scene = struct {
    @allow_deprecated_struct_defaults
    background_rgb uint32 = 0xFF77FF; // fuchsia is the default background
    foreground_rgb uint32; // there is no default foreground color
};
// [END defaults]

// [START primitives]
// A record which contains fields of a few primitive types.
type Sprite = struct {
    x float32;
    y float32;
    index uint32;
    color uint32;
    visible bool;
};
// [END primitives]

// [START bits]
type InfoFeatures = strict bits : uint8 {
    /// If present, this device represents WLAN hardware
    WLAN = 0x01;
    /// If present, this device is synthetic (not backed by h/w)
    SYNTH = 0x02;
    /// If present, this device receives all messages it sends
    LOOPBACK = 0x04;
};

// Underlying type is assumed to be uint32.
type AllowableSegments = flexible bits {
    TOLL_ROADS = 0b001;
    HIGHWAYS = 0b010;
    BIKE_PATHS = 0b100;
};

const ROADS AllowableSegments = AllowableSegments.TOLL_ROADS | AllowableSegments.HIGHWAYS;
// [END bits]

// [START enums]
type Beverage = flexible enum : uint8 {
    WATER = 0;
    COFFEE = 1;
    TEA = 2;
    WHISKEY = 3;
};

// Underlying type is assumed to be uint32.
type Vessel = strict enum {
    CUP = 0;
    BOWL = 1;
    TUREEN = 2;
    JUG = 3;
};
// [END enums]

// [START enum-use]
// A record which contains two enum fields.
type Order = struct {
    beverage Beverage;
    vessel Vessel;
};
// [END enum-use]

// [START arrays]
// A record which contains some arrays.
type Arrays = struct {
    // array of exactly 16 floating point numbers
    matrix array<float32, 16>;

    // array of exactly 10 arrays of 4 strings each
    form array<array<string, 4>, 10>;
};
// [END arrays]

// [START strings]
// A record which contains some strings.
type Document = struct {
    // title string, maximum of 40 bytes long
    title string:40;

    // description string, may be null, no upper bound on size
    description string:optional;
};
// [END strings]

// [START vectors]
// A record which contains some vectors.
type Vectors = struct {
    // a vector of up to 10 integers
    params vector<int32>:10;

    // a vector of bytes, no upper bound on size
    blob vector<uint8>;

    // a nullable vector of up to 24 strings
    nullable_vector_of_strings vector<string>:<24, optional>;

    // a vector of nullable strings, no upper bound on size
    vector_of_nullable_strings vector<string:optional>;

    // a vector of vectors of 16-element arrays of floating point numbers
    complex vector<vector<array<float32, 16>>>;
};
// [END vectors]

// [START handles]
// A record which contains some handles.
type Handles = resource struct {
    // a handle of unspecified type
    h zx.handle;

    // an optional channel
    c zx.handle:<CHANNEL, optional>;
};
// [END handles]

// [START tables]
type Profile = table {
    1: locales vector<string>;
    2: calendars vector<string>;
    3: time_zones vector<string>;
};
// [END tables]

type Left = struct {};

type Right = struct {};

// [START unions-use]
type Either = strict union {
    1: left Left;
    2: right Right;
};
// [END unions-use]

// [START strict-vs-flexible]
type FlexibleEither = flexible union {
    1: left Left;
    2: right Right;
};
// [END strict-vs-flexible]

protocol RealCalculator {};

// [START endpoints]
// A record which contains protocol-bound channels.
type Record = resource struct {
    // client endpoint of a channel bound to the Calculator protocol
    c client_end:Calculator;

    // server endpoint of a channel bound to the Science protocol
    s server_end:Science;

    // optional client endpoint of a channel bound to the
    // RealCalculator protocol
    r client_end:<RealCalculator, optional>;
};
// [END endpoints]

// [START composition-base]
protocol SceneryController {
    SetBackground(struct {
        color Color;
    });
    SetForeground(struct {
        color Color;
    });
};
// [END composition-base]

// [START composition-inherit]
protocol Drawer {
    compose SceneryController;
    Circle(struct {
        x int32;
        y int32;
        radius int32;
    });
    Square(struct {
        x int32;
        y int32;
        diagonal int32;
    });
};

protocol Writer {
    compose SceneryController;
    Text(struct {
        x int32;
        y int32;
        message string;
    });
};
// [END composition-inherit]

// [START composition-multiple-1]
protocol FontController {
    SetPointSize(struct {
        points int32;
    });
    SetFontName(struct {
        fontname string;
    });
    Italic(struct {
        onoff bool;
    });
    Bold(struct {
        onoff bool;
    });
    Underscore(struct {
        onoff bool;
    });
    Strikethrough(struct {
        onoff bool;
    });
};
// [END composition-multiple-1]

type Time = struct {};

// [START layering-clock]
protocol Clock {
    Now() -> (struct {
        time Time;
    });
    CurrentTimeZone() -> (struct {
        timezone string;
    });
};
// [END layering-clock]

// [START layering-horologist]
protocol Horologist {
    SetTime(struct {
        time Time;
    });
    SetCurrentTimeZone(struct {
        timezone string;
    });
};
// [END layering-horologist]

// [START layering-systemclock]
protocol SystemClock {
    compose Clock;
    compose Horologist;
};
// [END layering-systemclock]

// [START aliasing]
alias StoryID = string:MAX;
alias Chapters = vector<StoryID>:5;
// [END aliasing]

// [START aliasing-usage]
type Message = struct {
    baseline StoryID;
    chapters Chapters;
};
// [END aliasing-usage]

// [START builtin-aliases]
type RawBytes = struct {
    head byte;
    rest vector<uint8>;
};
// [END builtin-aliases]

// [START calculator]
type DivisionError = strict enum : uint32 {
    DIVIDE_BY_ZERO = 1;
};

protocol Calculator {
    Add(struct {
        a int32;
        b int32;
    }) -> (struct {
        sum int32;
    });
    Divide(struct {
        dividend int32;
        divisor int32;
    }) -> (struct {
        quotient int32;
        remainder int32;
    }) error DivisionError;
    Clear();
    -> OnError(struct {
        status_code uint32;
    });
};
// [END calculator]

// [START maximum-recursion-depth]
type InlineObject = struct {
    content_a string;
    vector vector<OutOfLineStructAtLevel1>;
    table TableInlineAtLevel0;
};

type OutOfLineStructAtLevel1 = struct {
    content_b string;
};

type TableInlineAtLevel0 = table {
    1: content_c string;
};
// [END maximum-recursion-depth]
