// Copyright 2021 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.

// ============================================================================
// This is an accompanying example code for the C++ async response tutorial.
// Head over there for the full walk-through:
// https://fuchsia.dev/fuchsia-src/development/languages/fidl/tutorials/cpp/basics/domain-objects
// ============================================================================

#include <type_traits>

#include <gtest/gtest.h>

// [START include]
#include <fidl/fuchsia.examples/cpp/fidl.h>
// [END include]

namespace {

//
// Examples of using the natural types.
//

// Verify that the wire types are available.
using WireFileMode = fuchsia_examples::wire::FileMode;
using ProtocolMarker = fuchsia_examples::Echo;

// [START natural-bits]
TEST(NaturalTypes, Bits) {
  // Bits implement bitwise operators such as |, ~, &, ^.
  auto flags = ~fuchsia_examples::FileMode::kRead & fuchsia_examples::FileMode::kExecute;
  flags = fuchsia_examples::FileMode::kRead | fuchsia_examples::FileMode::kWrite;

  // Bits implement the set difference operation (clearing bits) under -.
  ASSERT_EQ(flags - fuchsia_examples::FileMode::kRead, fuchsia_examples::FileMode::kWrite);
  flags -= fuchsia_examples::FileMode::kRead;
  ASSERT_EQ(flags, fuchsia_examples::FileMode::kWrite);

  // Bits may be explicitly casted to their underlying integer type.
  flags = fuchsia_examples::FileMode::kRead | fuchsia_examples::FileMode::kWrite;
  ASSERT_EQ(static_cast<uint16_t>(flags), 0b11);

  // They may also be explicitly constructed from an underlying type, but
  // this may result in invalid values for strict bits.
  flags = fuchsia_examples::FileMode(0b11);

  // A safer alternative is |TryFrom|, which constructs an instance of
  // |FileMode| only if underlying primitive does not contain any unknown
  // members that is not defined in the FIDL schema. Otherwise, returns
  // |std::nullopt|.
  std::optional<fuchsia_examples::FileMode> maybe_flags =
      fuchsia_examples::FileMode::TryFrom(0b1111);
  ASSERT_FALSE(maybe_flags.has_value());

  // Another alternative is |TruncatingUnknown| which clears any bits not
  // defined in the FIDL schema.
  fuchsia_examples::FileMode truncated_flags =
      fuchsia_examples::FileMode::TruncatingUnknown(0b1111);
  ASSERT_EQ(truncated_flags, fuchsia_examples::FileMode(0b111));

  // Bits implement bitwise-assignment.
  flags |= fuchsia_examples::FileMode::kExecute;

  // They also support equality and expose a |kMask| that is the
  // bitwise OR of all defined bit members.
  ASSERT_EQ(flags, fuchsia_examples::FileMode::kMask);

  // A flexible bits type additionally supports querying the unknown bits.
  fuchsia_examples::FlexibleFileMode flexible_flags = fuchsia_examples::FlexibleFileMode(0b1111);
  ASSERT_TRUE(flexible_flags.has_unknown_bits());
  ASSERT_EQ(static_cast<uint16_t>(flexible_flags.unknown_bits()), 0b1000);
}
// [END natural-bits]

// [START natural-enums]
TEST(NaturalTypes, Enums) {
  // Enums members are scoped constants under the enum type.
  fuchsia_examples::LocationType location = fuchsia_examples::LocationType::kAirport;

  // They may be explicitly casted to their underlying type.
  ASSERT_EQ(static_cast<uint32_t>(fuchsia_examples::LocationType::kMuseum), 1u);

  // They may also be casted to their underlying type without specifying the precise type.
  uint32_t strict_underlying = fidl::ToUnderlying(fuchsia_examples::LocationType::kMuseum);
  ASSERT_EQ(strict_underlying, 1u);

  // Enums support switch case statements.
  // A strict enum can be switched exhaustively.
  (void)[=] {
    switch (location) {
      case fuchsia_examples::LocationType::kAirport:
        return 1;
      case fuchsia_examples::LocationType::kMuseum:
        return 2;
      case fuchsia_examples::LocationType::kRestaurant:
        return 3;
    }
  };

  // A flexible enum requires a `default:` case.
  fuchsia_examples::FlexibleLocationType flexible_location =
      fuchsia_examples::FlexibleLocationType::kAirport;
  (void)[=] {
    switch (flexible_location) {
      case fuchsia_examples::FlexibleLocationType::kAirport:
        return 1;
      case fuchsia_examples::FlexibleLocationType::kMuseum:
        return 2;
      case fuchsia_examples::FlexibleLocationType::kRestaurant:
        return 3;
      default:  // Removing this branch will fail to compile.
        return 4;
    }
  };

  // A flexible enum also supports asking if the current enum value was
  // not known in the FIDL schema, or marked with `@unknown`.
  ASSERT_FALSE(flexible_location.IsUnknown());

  // Strict enums may be uninitialized. Their value will be undefined.
  fuchsia_examples::LocationType strict_location;
  (void)strict_location;

  // Flexible enums may be default initialized. They will either contain
  // the member marked with `@unknown` in the FIDL schema if exists,
  // or a compiler-reserved unknown value otherwise.
  fuchsia_examples::FlexibleLocationType default_flexible_location;
  ASSERT_TRUE(default_flexible_location.IsUnknown());
}
// [END natural-enums]

// [START natural-structs]
TEST(NaturalTypes, Structs) {
  // Structs may be default constructed with fields set to default values,
  // provided that all fields are also default constructible.
  fuchsia_examples::Color default_color;
  ASSERT_EQ(default_color.id(), 0u);
  ASSERT_EQ(default_color.name(), "red");

  // They support constructing by supplying fields in a sequence.
  fuchsia_examples::Color blue = {1, "blue"};
  ASSERT_EQ(blue.id(), 1u);

  // They also support a more readable syntax that names individual fields,
  // similar to C++ designated initialization. The double brace (`{{`) syntax
  // is necessary to workaround C++ limitations on aggregate initialization.
  fuchsia_examples::Color red{{.id = 2, .name = "red"}};
  ASSERT_EQ(red.id(), 2u);
  fuchsia_examples::Color designated_1 = {{.id = 1, .name = "designated"}};
  ASSERT_EQ(designated_1.id(), 1u);
  fuchsia_examples::Color designated_2{{.id = 2, .name = "designated"}};
  ASSERT_EQ(designated_2.id(), 2u);

  // Setters take the value to be set as argument.
  fuchsia_examples::Color color;
  color.id(100);
  color.name("green");
  ASSERT_EQ(color.id(), 100u);
  ASSERT_EQ(color.name(), "green");

  // Setters may also be chained.
  color.id(42).name("yellow");
  ASSERT_EQ(color.id(), 42u);
  ASSERT_EQ(color.name(), "yellow");

  // Equality is implemented for value types.
  ASSERT_EQ(color, fuchsia_examples::Color(42, "yellow"));

  // Copies and moves.
  fuchsia_examples::Color color_copy{color};
  ASSERT_EQ(color_copy.name(), "yellow");
  fuchsia_examples::Color color_moved{std::move(color)};
  ASSERT_EQ(color_moved.name(), "yellow");
  // The state of |color| is now unspecified.
}
// [END natural-structs]

// [START natural-unions]
TEST(NaturalTypes, Unions) {
  // Factory functions are used to construct natural union objects.
  // To construct a union whose active member is |int_value|, use |WithIntValue|.
  auto int_val = fuchsia_examples::JsonValue::WithIntValue(1);

  // |Which| obtains an enum corresponding to the active member, which may be
  // used in switch cases.
  ASSERT_EQ(int_val.Which(), fuchsia_examples::JsonValue::Tag::kIntValue);

  // When directly accessing a field, one must first check if the field is
  // active before dereferencing it.
  ASSERT_TRUE(int_val.int_value().has_value());
  ASSERT_TRUE(static_cast<bool>(int_val.int_value()));
  ASSERT_EQ(int_val.int_value().value(), 1);

  // Another example, this time activating the |string_value| member.
  auto str_val = fuchsia_examples::JsonValue::WithStringValue("1");
  ASSERT_EQ(str_val.Which(), fuchsia_examples::JsonValue::Tag::kStringValue);
  ASSERT_TRUE(str_val.string_value().has_value());

  // Unions are not default constructible, to avoid invalid states.
  static_assert(!std::is_default_constructible_v<fuchsia_examples::JsonValue>,
                "Unions cannot be default constructed");

  fuchsia_examples::JsonValue value = fuchsia_examples::JsonValue::WithStringValue("hello");
  ASSERT_FALSE(value.int_value());
  ASSERT_TRUE(value.string_value());

  // |value_or| returns a fallback if the corresponding member is not active.
  ASSERT_EQ(value.int_value().value_or(42), 42);

  // Setters take the value to be set as argument.
  // Setting a field causes that field to become the active member.
  value.int_value(2);
  ASSERT_TRUE(value.int_value());
  ASSERT_FALSE(value.string_value());

  // |take| invokes the move operation on the member if it is active.
  value.string_value("foo");
  std::optional<std::string> str = value.string_value().take();
  ASSERT_TRUE(str.has_value());
  ASSERT_EQ(str.value(), "foo");

  // Equality is implemented for value types.
  value.string_value("bar");
  ASSERT_EQ(value, fuchsia_examples::JsonValue::WithStringValue("bar"));

  // Copies and moves.
  fuchsia_examples::JsonValue value_copy{value};
  ASSERT_EQ(value.string_value().value(), "bar");
  fuchsia_examples::JsonValue value_moved{std::move(value)};
  ASSERT_EQ(value_moved.string_value().value(), "bar");

  // When switching over the tag from a flexible union, one must add a `default:`
  // case, to handle members not understood by the FIDL schema or to handle
  // newly added members in a source compatible way.
  fuchsia_examples::FlexibleJsonValue flexible_value =
      fuchsia_examples::FlexibleJsonValue::WithIntValue(1);
  switch (flexible_value.Which()) {
    case fuchsia_examples::FlexibleJsonValue::Tag::kIntValue:
      ASSERT_EQ(flexible_value.int_value().value(), 1);
      break;
    case fuchsia_examples::FlexibleJsonValue::Tag::kStringValue:
      FAIL() << "Unexpected tag. |flexible_value| was set to int";
      break;
    default:  // Removing this branch will fail to compile.
      break;
  }
}
// [END natural-unions]

// [START natural-tables]
TEST(NaturalTypes, Tables) {
  // A default constructed table is empty. That is, every field is absent.
  fuchsia_examples::User user;
  ASSERT_TRUE(user.IsEmpty());

  // Each accessor returns a |std::optional<T>|, where |T| is the field type.
  ASSERT_FALSE(user.age().has_value());

  // Setters take the value to be set as argument.
  user.age(100);
  user.age(*user.age() + 100);
  ASSERT_EQ(user.age().value(), 200);

  // Setters may also be chained.
  user.name("foo").age(30);
  ASSERT_EQ(user.name().value(), "foo");
  ASSERT_EQ(user.age().value(), 30);

  // Since each field is an |std::optional<T>|, they may also be cleared.
  user.name().reset();
  ASSERT_FALSE(user.name().has_value());

  // Assigning an |std::nullopt| also clears the field.
  user.name("bar");
  ASSERT_TRUE(user.name().has_value());
  user.name() = std::nullopt;
  ASSERT_FALSE(user.name().has_value());

  // |value_or| returns a fallback if the corresponding field is absent.
  ASSERT_EQ(user.name().value_or("anonymous"), "anonymous");
  user.age().reset();
  ASSERT_TRUE(user.IsEmpty());

  // Similar to structs, tables support constructing by naming individual fields.
  // Fields that are omitted from the designated initialization syntax will be
  // absent from the table.
  user = {{.age = 100, .name = "foo"}};
  ASSERT_TRUE(user.age());
  ASSERT_TRUE(user.name());

  user = {{.age = 100}};
  ASSERT_TRUE(user.age());
  ASSERT_FALSE(user.name());

  // Equality is implemented for value types.
  ASSERT_EQ(user, fuchsia_examples::User{{.age = 100}});

  // Copies and moves.
  fuchsia_examples::User user_copy{user};
  ASSERT_EQ(*user.age(), 100);
  fuchsia_examples::User user_moved{std::move(user)};
  ASSERT_EQ(*user_moved.age(), 100);
}
// [END natural-tables]

//
// Examples of using the wire types.
//

// [START wire-bits]
TEST(WireTypes, Bits) {
  static_assert(std::is_same<fuchsia_examples::FileMode, fuchsia_examples::wire::FileMode>::value,
                "natural bits should be equivalent to wire bits");
  static_assert(fuchsia_examples::FileMode::kMask == fuchsia_examples::wire::FileMode::kMask,
                "natural bits should be equivalent to wire bits");

  using fuchsia_examples::wire::FileMode;
  auto flags = FileMode::kRead | FileMode::kWrite | FileMode::kExecute;
  ASSERT_EQ(flags, FileMode::kMask);
}
// [END wire-bits]

// [START wire-enums]
TEST(WireTypes, Enums) {
  static_assert(
      std::is_same<fuchsia_examples::LocationType, fuchsia_examples::wire::LocationType>::value,
      "natural enums should be equivalent to wire enums");

  ASSERT_EQ(static_cast<uint32_t>(fuchsia_examples::wire::LocationType::kMuseum), 1u);
}
// [END wire-enums]

// [START wire-structs]
TEST(WireTypes, Structs) {
  // Wire structs are simple C++ structs with all their member fields declared
  // public. One may invoke aggregate initialization:
  fuchsia_examples::wire::Color blue = {1, "blue"};
  ASSERT_EQ(blue.id, 1u);
  ASSERT_EQ(blue.name.get(), "blue");

  // ..or designated initialization.
  fuchsia_examples::wire::Color blue_designated = {.id = 1, .name = "blue"};
  ASSERT_EQ(blue_designated.id, 1u);
  ASSERT_EQ(blue_designated.name.get(), "blue");

  // A wire struct may be default constructed, but user-defined default values
  // are not supported.
  // Default-initializing a struct means all fields are zero-initialized.
  fuchsia_examples::wire::Color default_color;
  ASSERT_EQ(default_color.id, 0u);
  ASSERT_TRUE(default_color.name.is_null());
  ASSERT_TRUE(default_color.name.empty());

  // There are no getters/setters. One simply reads or mutates the member field.
  blue.id = 2;
  ASSERT_EQ(blue.id, 2u);

  // Here we demonstrate that wire structs do not own their out-of-line children.
  // Copying a struct will not copy their out-of-line children. Pointers are
  // simply aliased.
  {
    fuchsia_examples::wire::Color blue2 = blue;
    ASSERT_EQ(blue2.name.data(), blue.name.data());
  }
  // Similarly, destroying a wire struct object does not destroy out-of-line
  // children. Destroying |blue2| does not invalidate the string contents in |name|.
  ASSERT_EQ(blue.name.get(), "blue");
}
// [END wire-structs]

// [START wire-unions]
TEST(WireTypes, Unions) {
  // When the active member is larger than 4 bytes, it is stored out-of-line,
  // and the union will borrow the out-of-line content. The lifetimes can be
  // tricky to reason about, hence the FIDL runtime provides a |fidl::AnyArena|
  // interface for arena-based allocation of members. The built-in
  // implementation is |fidl::Arena|.
  //
  // Pass the arena as the first argument to |With...| factory functions, to
  // construct the member content on the arena, and have the union reference it.
  fidl::Arena arena;
  fuchsia_examples::wire::JsonValue str_union =
      fuchsia_examples::wire::JsonValue::WithStringValue(arena, "1");

  // |Which| obtains an enum corresponding to the active member, which may be
  // used in switch cases.
  ASSERT_EQ(str_union.Which(), fuchsia_examples::wire::JsonValue::Tag::kStringValue);

  // Before accessing the |string_value| member, one should check if the union
  // indeed currently holds this member, by querying |is_string_value|.
  // Accessing the wrong member will cause a panic.
  ASSERT_TRUE(str_union.is_string_value());
  ASSERT_EQ("1", str_union.string_value().get());

  // When the active member is smaller or equal to 4 bytes, such as an
  // |int32_t| here, the entire member is inlined into the union object.
  // In these cases, arena allocation is not necessary, and the union
  // object wholly owns the member.
  fuchsia_examples::wire::JsonValue int_union = fuchsia_examples::wire::JsonValue::WithIntValue(1);
  ASSERT_TRUE(int_union.is_int_value());
  ASSERT_EQ(1, int_union.int_value());

  // A default constructed wire union is invalid.
  // It must be initialized with a valid member before use.
  // One is not allowed to send invalid unions through FIDL client/server APIs.
  fuchsia_examples::wire::JsonValue default_union;
  ASSERT_TRUE(default_union.has_invalid_tag());
  default_union = fuchsia_examples::wire::JsonValue::WithStringValue(arena, "hello");
  ASSERT_FALSE(default_union.has_invalid_tag());
  ASSERT_TRUE(default_union.is_string_value());
  ASSERT_EQ(default_union.string_value().get(), "hello");

  // Optional unions are represented with |fidl::WireOptional|.
  fidl::WireOptional<fuchsia_examples::wire::JsonValue> optional_json;
  ASSERT_FALSE(optional_json.has_value());
  optional_json = fuchsia_examples::wire::JsonValue::WithIntValue(42);
  ASSERT_TRUE(optional_json.has_value());
  // |fidl::WireOptional| has a |std::optional|-like API.
  fuchsia_examples::wire::JsonValue& value = optional_json.value();
  ASSERT_TRUE(value.is_int_value());

  // When switching over the tag from a flexible union, one must add a `default:`
  // case, to handle members not understood by the FIDL schema or to handle
  // newly added members in a source compatible way.
  fuchsia_examples::wire::FlexibleJsonValue flexible_value =
      fuchsia_examples::wire::FlexibleJsonValue::WithIntValue(1);
  switch (flexible_value.Which()) {
    case fuchsia_examples::wire::FlexibleJsonValue::Tag::kIntValue:
      ASSERT_EQ(flexible_value.int_value(), 1);
      break;
    case fuchsia_examples::wire::FlexibleJsonValue::Tag::kStringValue:
      FAIL() << "Unexpected tag. |flexible_value| was set to int";
      break;
    default:  // Removing this branch will fail to compile.
      break;
  }
}
// [END wire-unions]

// [START wire-tables]
TEST(WireTypes, Tables) {
  fidl::Arena arena;
  // To construct a wire table, you need to first create a corresponding
  // |Builder| object, which borrows an arena. The |arena| will be used to
  // allocate the table frame, a bookkeeping structure for field presence.
  auto builder = fuchsia_examples::wire::User::Builder(arena);

  // To set a table field, call the member function with the same name on the
  // builder. The arguments will be forwarded to the field constructor, and the
  // field is allocated on the initial |arena|.
  builder.age(10);

  // Note that only the inline portion of the field is automatically placed in
  // the arena. The field itself may reference its own out-of-line content,
  // such as in the case of |name| whose type is |fidl::StringView|. |name|
  // will reference the "jdoe" literal, which lives in static program storage.
  builder.name("jdoe");

  // Call |Build| to finalize the table builder into a |User| table.
  // The builder is no longer needed after this point. |user| will continue to
  // reference objects allocated in the |arena|.
  fuchsia_examples::wire::User user = builder.Build();
  ASSERT_FALSE(user.IsEmpty());

  // Before accessing a field, one should check if it is present, by querying
  // |has_...|. Accessing an absent field will panic.
  ASSERT_TRUE(user.has_name());
  ASSERT_EQ(user.name().get(), "jdoe");

  // Setters may be chained, leading to a fluent syntax.
  user = fuchsia_examples::wire::User::Builder(arena).age(30).name("bob").Build();
  ASSERT_FALSE(user.IsEmpty());
  ASSERT_TRUE(user.has_age());
  ASSERT_EQ(user.age(), 30);
  ASSERT_TRUE(user.has_name());
  ASSERT_EQ(user.name().get(), "bob");

  // A default constructed wire table is empty.
  // This is mostly useful to make requests or replies with empty tables.
  fuchsia_examples::wire::User defaulted_user;
  ASSERT_TRUE(defaulted_user.IsEmpty());

  // In some situations it could be difficult to provide an arena when
  // constructing tables. For example, here it is hard to provide constructor
  // arguments to 10 tables at once. Because a default constructed wire table is
  // empty, a new table instance should be built and assigned in its place.
  fidl::Array<fuchsia_examples::wire::User, 10> users;
  for (auto& user : users) {
    ASSERT_TRUE(user.IsEmpty());
    user = fuchsia_examples::wire::User::Builder(arena).age(30).Build();
    ASSERT_FALSE(user.IsEmpty());
    ASSERT_EQ(user.age(), 30);
  }
  ASSERT_EQ(users[0].age(), 30);

  // Finally, tables support checking if it was received with unknown fields.
  // A table created by ourselves will never have unknown fields.
  ASSERT_FALSE(user.HasUnknownData());
}
// [END wire-tables]

//
// Examples of converting between wire and natural types.
//

// [START natural-to-wire]
TEST(Conversion, NaturalToWire) {
  // Let's start with a natural table.
  fuchsia_examples::User user{{.age = 100, .name = "foo"}};

  // To convert it to its corresponding wire domain object, we need a
  // |fidl::AnyArena| implementation to allocate the storage, here an |arena|.
  fidl::Arena arena;

  // Call |fidl::ToWire| with the arena and the natural domain object.
  // All out-of-line fields will live on the |arena|.
  fuchsia_examples::wire::User wire_user = fidl::ToWire(arena, user);
  ASSERT_TRUE(wire_user.has_age());
  ASSERT_EQ(wire_user.age(), 100);
  ASSERT_TRUE(wire_user.has_name());
  ASSERT_EQ(wire_user.name().get(), "foo");
}
// [END natural-to-wire]

// [START wire-to-natural]
TEST(Conversion, WireToNatural) {
  fidl::Arena arena;

  // Let's start with a wire table.
  fuchsia_examples::wire::User wire_user =
      fuchsia_examples::wire::User::Builder(arena).age(30).name("bob").Build();

  // Call |fidl::ToNatural| with the wire domain object.
  // All child fields will be owned by |user|.
  fuchsia_examples::User user = fidl::ToNatural(wire_user);
  ASSERT_TRUE(user.age().has_value());
  ASSERT_EQ(user.age().value(), 30);
  ASSERT_TRUE(user.name().has_value());
  ASSERT_EQ(user.name().value(), "bob");
}
// [END wire-to-natural]

}  // namespace
