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

#include "lib/fidl-async-2/fidl_struct.h"

#include <fidl/fidl.types.test/cpp/fidl.h>
#include <fidl/types/test/c/fidl.h>
#include <inttypes.h>
#include <lib/fidl/llcpp/vector_view.h>
#include <lib/zx/event.h>

#include <type_traits>

#include <zxtest/zxtest.h>

namespace {

template <typename C, typename Enable = void>
struct HasCopyAsLlcpp : std::false_type {};
template <typename C>
struct HasCopyAsLlcpp<
    C, typename std::enable_if<std::is_same<decltype(std::declval<C>().CopyAsLlcpp()),
                                            typename C::llcpp_type>::value>::type>
    : std::true_type {};

}  // namespace

using namespace ::fidl_types_test;

TEST(FidlStruct, CopyableStruct) {
  constexpr int32_t kNewFieldValue = 12;
  using Struct = FidlStruct<fidl_types_test_CopyableStruct, wire::CopyableStruct>;
  Struct s(Struct::Default);
  const Struct& sc = s;
  EXPECT_EQ(0, s->x);
  s->x = kNewFieldValue;
  EXPECT_EQ(kNewFieldValue, s->x);
  static_assert(HasCopyAsLlcpp<Struct>::value);
  EXPECT_EQ(kNewFieldValue, s.CopyAsLlcpp().x);
  EXPECT_EQ(kNewFieldValue, s.BorrowAsLlcpp().x);
  EXPECT_EQ(kNewFieldValue, sc.BorrowAsLlcpp().x);
  fidl_types_test_CopyableStruct* ps = s.get();
  const fidl_types_test_CopyableStruct* cps = s.get();
  EXPECT_EQ(kNewFieldValue, ps->x);
  EXPECT_EQ(kNewFieldValue, cps->x);
  EXPECT_EQ(kNewFieldValue, Struct::BorrowAsLlcpp(ps)->x);
  EXPECT_EQ(kNewFieldValue, Struct::BorrowAsLlcpp(cps)->x);
  EXPECT_EQ(kNewFieldValue, s.TakeAsLlcpp().x);
  // TakeAsLlcpp() moved it out.
  EXPECT_FALSE(!!s);
}

TEST(FidlStruct, StructWithArrays) {
  constexpr int32_t kNewFieldValue = 12;
  using Struct = FidlStruct<fidl_types_test_StructWithArrays, wire::StructWithArrays>;
  Struct s(Struct::Default);
  const Struct& sc = s;
  EXPECT_EQ(0, s->x);
  s->x = kNewFieldValue;
  EXPECT_EQ(kNewFieldValue, s->x);
  static_assert(HasCopyAsLlcpp<Struct>::value);
  EXPECT_EQ(kNewFieldValue, s.CopyAsLlcpp().x);
  EXPECT_EQ(kNewFieldValue, s.BorrowAsLlcpp().x);
  EXPECT_EQ(kNewFieldValue, sc.BorrowAsLlcpp().x);
  fidl_types_test_StructWithArrays* ps = s.get();
  const fidl_types_test_StructWithArrays* cps = s.get();
  EXPECT_EQ(kNewFieldValue, ps->x);
  EXPECT_EQ(kNewFieldValue, cps->x);
  EXPECT_EQ(kNewFieldValue, Struct::BorrowAsLlcpp(ps)->x);
  EXPECT_EQ(kNewFieldValue, Struct::BorrowAsLlcpp(cps)->x);
  EXPECT_EQ(kNewFieldValue, s.TakeAsLlcpp().x);
  // TakeAsLlcpp() moved it out.
  EXPECT_FALSE(!!s);
}

TEST(FidlStruct, StructWithSubStruct) {
  constexpr int32_t kNewFieldValue = 12;
  using Struct = FidlStruct<fidl_types_test_StructWithSubStruct, wire::StructWithSubStruct>;
  Struct s(Struct::Default);
  const Struct& sc = s;
  EXPECT_EQ(0, s->s.x);
  s->s.x = kNewFieldValue;
  EXPECT_EQ(kNewFieldValue, s->s.x);
  static_assert(HasCopyAsLlcpp<Struct>::value);
  EXPECT_EQ(kNewFieldValue, s.CopyAsLlcpp().s.x);
  EXPECT_EQ(kNewFieldValue, s.BorrowAsLlcpp().s.x);
  EXPECT_EQ(kNewFieldValue, sc.BorrowAsLlcpp().s.x);
  fidl_types_test_StructWithSubStruct* ps = s.get();
  const fidl_types_test_StructWithSubStruct* cps = s.get();
  EXPECT_EQ(kNewFieldValue, ps->s.x);
  EXPECT_EQ(kNewFieldValue, cps->s.x);
  EXPECT_EQ(kNewFieldValue, Struct::BorrowAsLlcpp(ps)->s.x);
  EXPECT_EQ(kNewFieldValue, Struct::BorrowAsLlcpp(cps)->s.x);
  EXPECT_EQ(kNewFieldValue, s.TakeAsLlcpp().s.x);
  // TakeAsLlcpp() moved it out.
  EXPECT_FALSE(!!s);
}

TEST(FidlStruct, EmptyStruct) {
  using Struct = FidlStruct<fidl_types_test_EmptyStruct, wire::EmptyStruct>;
  Struct s(Struct::Default);
  const Struct& sc = s;
  static_assert(HasCopyAsLlcpp<Struct>::value);
  (void)s.CopyAsLlcpp();
  (void)s.BorrowAsLlcpp();
  (void)sc.BorrowAsLlcpp();
  fidl_types_test_EmptyStruct* ps = s.get();
  const fidl_types_test_EmptyStruct* cps = s.get();
  (void)Struct::BorrowAsLlcpp(ps);
  (void)Struct::BorrowAsLlcpp(cps);
  (void)s.TakeAsLlcpp();
  // TakeAsLlcpp() moved it out.
  EXPECT_FALSE(!!s);
}

// If this builds, it passes.
TEST(FidlStruct, TypeAliases) {
  using Struct = FidlStruct<fidl_types_test_EmptyStruct, wire::EmptyStruct>;
  static_assert(std::is_same<Struct::c_type, fidl_types_test_EmptyStruct>::value);
  static_assert(std::is_same<Struct::llcpp_type, wire::EmptyStruct>::value);
}
