// Copyright 2019 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/cpp/comparison.h>
#include <lib/fidl/cpp/test/test_util.h>

#include <vector>

#include <fidl/test/misc/cpp/fidl.h>
#include <zxtest/zxtest.h>

namespace fidl {
namespace {

TEST(XUnion, SetterReturnsSelf) {
  using test::misc::SampleXUnion;
  using test::misc::SimpleTable;

  SimpleTable st;
  st.set_x(42);

  SampleXUnion u;
  u.set_st(std::move(st));

  EXPECT_TRUE(u.is_st());
  EXPECT_EQ(42, u.st().x());

  EXPECT_TRUE(fidl::Equals(u, SampleXUnion().set_st(std::move(SimpleTable().set_x(42)))));
}

TEST(XUnion, EmptyXUnionEquality) {
  using test::misc::SampleXUnion;

  EXPECT_TRUE(::fidl::Equals(SampleXUnion(), SampleXUnion()));
}

TEST(XUnion, FlexibleXUnionsEquality) {
  using test::misc::SampleXUnion;
  using test::misc::SampleXUnionInStruct;

  std::vector<uint8_t> input = {
      0x11, 0xba, 0x5e, 0xba, 0x00, 0x00, 0x00, 0x00,  // invalid ordinal + padding
      0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // envelope: # of bytes + # of handles
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // envelope: data is present
      0xde, 0xad, 0xbe, 0xef, 0x5c, 0xa1, 0xab, 0x1e,  // fake out-of-line data
  };

  auto s = ::fidl::test::util::DecodedBytes<SampleXUnionInStruct>(input);
  auto xu = std::move(s.xu);

  auto s2 = ::fidl::test::util::DecodedBytes<SampleXUnionInStruct>(input);
  auto xu2 = std::move(s2.xu);

  EXPECT_EQ(xu.Which(), SampleXUnion::Tag::kUnknown);
  EXPECT_EQ(xu.Ordinal(), 0xba5eba11);
  EXPECT_EQ(*xu.UnknownBytes(),
            std::vector<uint8_t>(input.cbegin() + sizeof(fidl_xunion_t), input.cend()));

  EXPECT_EQ(xu.Ordinal(), xu2.Ordinal());
  EXPECT_EQ(*xu.UnknownBytes(), *xu2.UnknownBytes());
  EXPECT_TRUE(fidl::Equals(xu, xu2));

  std::vector<uint8_t> different_unknown_data = {
      0x11, 0xba, 0x5e, 0xba, 0x00, 0x00, 0x00, 0x00,  // invalid ordinal + padding
      0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // envelope: # of bytes + # of handles
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // envelope: data is present
      0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,  // DIFFERENT fake out-of-line data
  };

  auto s3 = ::fidl::test::util::DecodedBytes<SampleXUnionInStruct>(different_unknown_data);
  auto xu3 = std::move(s3.xu);

  EXPECT_EQ(xu.Ordinal(), xu3.Ordinal());
  EXPECT_NE(*xu.UnknownBytes(), *xu3.UnknownBytes());
  EXPECT_FALSE(fidl::Equals(xu, xu3));

  std::vector<uint8_t> different_ordinal = {
      0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,  // DIFFERENT invalid ordinal + padding
      0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // envelope: # of bytes + # of handles
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  // envelope: data is present
      0xde, 0xad, 0xbe, 0xef, 0x5c, 0xa1, 0xab, 0x1e,  // fake out-of-line data
  };

  auto s4 = ::fidl::test::util::DecodedBytes<SampleXUnionInStruct>(different_ordinal);
  auto xu4 = std::move(s4.xu);

  EXPECT_NE(xu.Ordinal(), xu4.Ordinal());
  EXPECT_EQ(*xu.UnknownBytes(), *xu4.UnknownBytes());
  EXPECT_FALSE(fidl::Equals(xu, xu4));
}

TEST(XUnion, XUnionFactoryFunctions) {
  using test::misc::SampleXUnion;
  using test::misc::SimpleTable;

  SampleXUnion prim_xu = SampleXUnion::WithI(123);

  EXPECT_EQ(prim_xu.i(), 123);
  EXPECT_EQ(prim_xu.Which(), SampleXUnion::Tag::kI);
  EXPECT_EQ(prim_xu.Ordinal(), SampleXUnion::Tag::kI);
  EXPECT_EQ(prim_xu.UnknownBytes(), nullptr);

  // Test passing an object with no copy constructor (only move) to the
  // factory function.
  SimpleTable tbl;
  SampleXUnion tbl_xu = SampleXUnion::WithSt(std::move(tbl));

  EXPECT_EQ(tbl_xu.Which(), SampleXUnion::Tag::kSt);
  EXPECT_EQ(tbl_xu.Ordinal(), SampleXUnion::Tag::kSt);
  EXPECT_EQ(tbl_xu.UnknownBytes(), nullptr);
}

// Confirms that an xunion can have a variant with both type and name identifiers as "empty" and not
// collide with any tags, internal or otherwise, indicating the xunion is in its unknown monostate.
TEST(XUnion, XUnionContainingEmptyStruct) {
  using test::misc::Empty;
  using test::misc::XUnionContainingEmptyStruct;

  XUnionContainingEmptyStruct xu;

  EXPECT_EQ(xu.Which(), XUnionContainingEmptyStruct::Tag::Invalid);
  EXPECT_FALSE(xu.is_empty());

  Empty empty;
  xu.set_empty(std::move(empty));
  EXPECT_EQ(xu.Which(), XUnionContainingEmptyStruct::Tag::kEmpty);
  EXPECT_TRUE(xu.is_empty());
}

}  // namespace
}  // namespace fidl
