// 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 "tools/kazoo/outputs.h"
#include "tools/kazoo/syscall_library.h"
#include "tools/kazoo/test.h"
#include "tools/kazoo/test_ir_test_ulib_bits.test.h"
#include "tools/kazoo/test_ir_test_ulib_enums.test.h"
#include "tools/kazoo/test_ir_test_ulib_type_aliases.test.h"
#include "tools/kazoo/test_ir_test_ulib_tables.test.h"

namespace {

constexpr const char* kPrelude = R"(// 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.

// WARNING: THIS FILE IS MACHINE GENERATED BY //tools/kazoo. DO NOT EDIT.

#ifndef LIB_ZXIO_TYPES_H_
#define LIB_ZXIO_TYPES_H_

#include <stdbool.h>
#include <stdint.h>
#include <zircon/compiler.h>

// This header defines the public types used in the zxio and zxio_ops interface.

__BEGIN_CDECLS
)";

constexpr const char* kEpilogue = R"(
__END_CDECLS

#endif  // LIB_ZXIO_TYPES_H_
)";

TEST(CUlibHeaderOutput, Bits) {
  SyscallLibrary library;
  ASSERT_TRUE(SyscallLibraryLoader::FromJson(k_test_ulib_bits, &library));

  Writer writer;
  ASSERT_TRUE(CUlibHeaderOutput(library, &writer));

  EXPECT_EQ(writer.Out(),
            std::string(kPrelude) + R"(
// Uint16 Bits -----------------------------------------------------------------

// Doc Comments for Uint16Bits
//
// Doc comments testing.
typedef uint16_t zxio_uint16_bits_t;

#define ZXIO_UINT16_BIT_NONE ((zxio_uint16_bits_t)0x0)

// Doc comment on bits member.
#define ZXIO_UINT16_BIT_FOO ((zxio_uint16_bits_t)0x1)

#define ZXIO_UINT16_BIT_ALL ((zxio_uint16_bits_t)0x1)

// No Doc Comment Bits ---------------------------------------------------------

typedef uint32_t zxio_no_doc_comment_bits_t;

#define ZXIO_NO_DOC_COMMENT_BIT_NONE ((zxio_no_doc_comment_bits_t)0x0u)

#define ZXIO_NO_DOC_COMMENT_BIT_FOO ((zxio_no_doc_comment_bits_t)0x1u)
#define ZXIO_NO_DOC_COMMENT_BIT_BAR ((zxio_no_doc_comment_bits_t)0x2u)

#define ZXIO_NO_DOC_COMMENT_BIT_ALL ((zxio_no_doc_comment_bits_t)0x3u)
)" + std::string(kEpilogue));
}

TEST(CUlibHeaderOutput, Enums) {
  SyscallLibrary library;
  ASSERT_TRUE(SyscallLibraryLoader::FromJson(k_test_ulib_enums, &library));

  Writer writer;
  ASSERT_TRUE(CUlibHeaderOutput(library, &writer));

  EXPECT_EQ(writer.Out(),
            std::string(kPrelude) + R"(
// Uint16 Enum -----------------------------------------------------------------

// Doc Comments for Uint16Enum
//
// Doc comments testing.
typedef uint16_t zxio_uint16_enum_t;

// Doc comment on enum member.
#define ZXIO_UINT16_ENUM_FOO ((zxio_uint16_enum_t)0x1)

// No Doc Comment Enum ---------------------------------------------------------

typedef uint32_t zxio_no_doc_comment_enum_t;

#define ZXIO_NO_DOC_COMMENT_ENUM_FOO ((zxio_no_doc_comment_enum_t)0x1u)
#define ZXIO_NO_DOC_COMMENT_ENUM_BAR ((zxio_no_doc_comment_enum_t)0x2u)
)" + std::string(kEpilogue));
}

TEST(CUlibHeaderOutput, TypeAliases) {
  SyscallLibrary library;
  ASSERT_TRUE(SyscallLibraryLoader::FromJson(k_test_ulib_type_aliases, &library));

  Writer writer;
  ASSERT_TRUE(CUlibHeaderOutput(library, &writer));

  EXPECT_EQ(writer.Out(),
            std::string(kPrelude) + R"(
// Destination -----------------------------------------------------------------

typedef uint32_t zxio_destination_t;

#define ZXIO_DESTINATION_FOO ((zxio_destination_t)0x1u)

// Test doc comment on type alias.
typedef zxio_destination_t zxio_alias_t;

typedef uint64_t zxio_alias_char_ptr_t;
)" + std::string(kEpilogue));
}

TEST(CUlibHeaderOutput, Tables) {
  SyscallLibrary library;
  ASSERT_TRUE(SyscallLibraryLoader::FromJson(k_test_ulib_tables, &library));

  Writer writer;
  ASSERT_TRUE(CUlibHeaderOutput(library, &writer));

  EXPECT_EQ(writer.Out(),
            std::string(kPrelude) + R"(
// Table where all members are optional.
//
// Optional fields have corresponding presence indicators. When creating
// a new object, it is desirable to use the ZXIO_TABLE_WITH_ALL_OPTIONAL_SET helper macro
// to set the fields, to avoid forgetting to change the presence indicator.
typedef struct zxio_table_with_all_optional {

  // foo doc comment.
  uint16_t foo;

  // bar doc comment.
  uint32_t bar;

  // Presence indicator for these fields.
  //
  // If a particular field is absent, it should be set to zero/none,
  // and the corresponding presence indicator will be false.
  // Therefore, a completely empty |zxio_table_with_all_optional_t| may be conveniently
  // obtained via value-initialization e.g. `zxio_table_with_all_optional_t a = {};`.
  struct zxio_table_with_all_optional_has_t {
    bool foo;
    bool bar;
  } has;
} zxio_table_with_all_optional_t;

#define ZXIO_TABLE_WITH_ALL_OPTIONAL_SET(table_with_all_optional, field_name, value) \
  do { \
    zxio_table_with_all_optional_t* _tmp_table_with_all_optional= &(table_with_all_optional); \
    _tmp_table_with_all_optional->field_name = value; \
    _tmp_table_with_all_optional->has.field_name = true; \
  } while (0)

// Table where some members are required.
//
// Optional fields have corresponding presence indicators. When creating
// a new object, it is desirable to use the ZXIO_TABLE_WITH_SOME_REQUIRED_SET helper macro
// to set the fields, to avoid forgetting to change the presence indicator.
typedef struct zxio_table_with_some_required {

  // foo doc comment.
  uint16_t foo;

  // Presence indicator for these fields.
  //
  // If a particular field is absent, it should be set to zero/none,
  // and the corresponding presence indicator will be false.
  // Therefore, a completely empty |zxio_table_with_some_required_t| may be conveniently
  // obtained via value-initialization e.g. `zxio_table_with_some_required_t a = {};`.
  struct zxio_table_with_some_required_has_t {
    bool foo;
  } has;

  // bar doc comment. This is required.
  uint32_t bar;
} zxio_table_with_some_required_t;

#define ZXIO_TABLE_WITH_SOME_REQUIRED_SET(table_with_some_required, field_name, value) \
  do { \
    zxio_table_with_some_required_t* _tmp_table_with_some_required= &(table_with_some_required); \
    _tmp_table_with_some_required->field_name = value; \
    _tmp_table_with_some_required->has.field_name = true; \
  } while (0)
)" + std::string(kEpilogue));
}

}  // namespace
