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

#include <lib/fidl/cpp/wire_format_metadata.h>
#include <zircon/assert.h>

#include <cstring>

namespace fidl {

WireFormatMetadata WireFormatMetadata::FromOpaque(fidl_opaque_wire_format_metadata_t opaque) {
  uint8_t bytes[8] = {};
  memcpy(bytes, &opaque, sizeof(opaque));
  WireFormatMetadata metadata;
  metadata.disambiguator_ = bytes[0];
  metadata.magic_number_ = bytes[1];
  metadata.at_rest_flags_[0] = bytes[2];
  metadata.at_rest_flags_[1] = bytes[3];
  metadata.reserved_[0] = bytes[4];
  metadata.reserved_[1] = bytes[5];
  metadata.reserved_[2] = bytes[6];
  metadata.reserved_[3] = bytes[7];
  return metadata;
}

WireFormatMetadata WireFormatMetadata::FromTransactionalHeader(fidl_message_header_t header) {
  WireFormatMetadata metadata;
  metadata.disambiguator_ = 0;
  metadata.magic_number_ = header.magic_number;
  // See
  // https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs/0138_handling_unknown_interactions?hl=en#transactional-message-header-v4
  //
  // At-rest flags come first, followed by dynamic flags.
  //
  // Note: the V1, V2, and "V2 after unknown interactions" FIDL wire formats all
  // store the at_rest flags in the same location. When a future FIDL revision
  // change the location of the at_rest flags, this would need to be updated to
  // be conditional on the magic number.
  metadata.at_rest_flags_[0] = header.at_rest_flags[0];
  metadata.at_rest_flags_[1] = header.at_rest_flags[1];
  memset(metadata.reserved_, 0, sizeof(metadata.reserved_));
  return metadata;
}

fidl_opaque_wire_format_metadata_t WireFormatMetadata::ToOpaque() const {
  // Translate the metadata to a binary representation.
  // We could use a for-loop or fancier serialization, but an array gives the
  // most explicit control over the ABI.
  uint8_t bytes[8] = {
      disambiguator_, magic_number_, at_rest_flags_[0], at_rest_flags_[1],
      reserved_[0],   reserved_[1],  reserved_[2],      reserved_[3],
  };
  uint64_t opaque;
  static_assert(sizeof(opaque) == sizeof(bytes), "Opaque metadata is 8 bytes");
  memcpy(&opaque, bytes, sizeof(opaque));
  return fidl_opaque_wire_format_metadata_t{opaque};
}

bool WireFormatMetadata::is_valid() const {
  // Note: this method should be in sync with |fidl_validate_txn_header|.
  return magic_number_ == kFidlWireFormatMagicNumberInitial;
}

internal::WireFormatVersion WireFormatMetadata::wire_format_version() const {
  ZX_ASSERT_MSG(is_valid(), "Invalid metadata %d %d %d", at_rest_flags_[0], at_rest_flags_[1],
                magic_number_);
  if ((at_rest_flags_[0] & FIDL_MESSAGE_HEADER_AT_REST_FLAGS_0_USE_VERSION_V2) == 0) {
    return internal::WireFormatVersion::kV1;
  }
  return internal::WireFormatVersion::kV2;
}

::FidlWireFormatVersion WireFormatMetadata::c_wire_format_version() const {
  switch (wire_format_version()) {
    case internal::WireFormatVersion::kV1:
      return FIDL_WIRE_FORMAT_VERSION_V1;
    case internal::WireFormatVersion::kV2:
      return FIDL_WIRE_FORMAT_VERSION_V2;
  }
  ZX_PANIC("Unsupported wire format version %d", static_cast<int>(wire_format_version()));
}

namespace internal {

// Constructs a |WireFormatMetadata| corresponding to the version.
WireFormatMetadata WireFormatMetadataForVersion(WireFormatVersion version) {
  WireFormatMetadata metadata;
  metadata.magic_number_ = kFidlWireFormatMagicNumberInitial;
  switch (version) {
    case WireFormatVersion::kV1:
      return metadata;
    case WireFormatVersion::kV2:
      metadata.at_rest_flags_[0] = FIDL_MESSAGE_HEADER_AT_REST_FLAGS_0_USE_VERSION_V2;
      return metadata;
  }
  ZX_PANIC("Unsupported wire format version %d", static_cast<int>(version));
}

}  // namespace internal
}  // namespace fidl
