// Copyright 2024 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/ld/fuchsia-debugdata.h"

#include <lib/fidl/txn_header.h>
#include <zircon/fidl.h>

#include <array>
#include <string_view>
#include <type_traits>

namespace ld {

// These are minimal hand-rolled marshalling functions for the one-way FIDL
// fuchsia.debugdata.Publisher/Publish, fuchsia.io.Directory/Open, and
// fuchsia.unknown.Cloneable/Clone messages.
//
// This code marshals FIDL wire format just as FIDL bindings would, but avoids
// the generated FIDL C++ bindings code because it is too heavy-weight for use
// in low-level environments.  This code uses direct marshalling code in local
// stack buffers of minimal size, with no dynamic allocation.

// TODO(https://fxbug.dev/42072760): This should be generated by Zither.

namespace {

constexpr uint64_t fuchsia_io_MAX_PATH_LENGTH = 4095;
constexpr uint64_t fuchsia_io_MAX_NAME_LENGTH = 255;
constexpr uint64_t fuchsia_io_Flags_PROTOCOL_SERVICE = 0x000100000000;
constexpr uint64_t fuchsia_io_DirectoryOpen_Ordinal = 0x568ddcb9a9cbb6d9;

constexpr std::string_view fuchsia_debugdata_Publisher_Name = "fuchsia.debugdata.Publisher";
static_assert(fuchsia_debugdata_Publisher_Name.size() <= fuchsia_io_MAX_PATH_LENGTH);
constexpr uint64_t fuchsia_debugdata_PublisherPublish_Ordinal = 0xf52f8806121e066;

constexpr uint64_t fuchsia_unknown_CloneableClone_Ordinal = 0x20d8a7aba2168a79;

fidl_message_header_t TxnHeader(uint64_t ordinal) {
  fidl_message_header_t hdr;
  fidl_init_txn_header(&hdr, 0, ordinal, 0);
  return hdr;
}

// To use no more stack space than needed for the request, this is specifically
// initialized with the exact constant path string that will be needed.
struct alignas(FIDL_ALIGNMENT) fuchsia_io_DirectoryOpenRequestForDebugdata {
  fuchsia_io_DirectoryOpenRequestForDebugdata() {
    fuchsia_debugdata_Publisher_Name.copy(path_buffer.data(), path_buffer.size());
  }

  size_t size_bytes() const { return FIDL_ALIGN(sizeof(fixed) + fixed.path.size); }

  struct alignas(FIDL_ALIGNMENT) {
    fidl_message_header_t hdr = TxnHeader(fuchsia_io_DirectoryOpen_Ordinal);
    fidl_string_t path = {
        .size = fuchsia_debugdata_Publisher_Name.size(),
        .data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT),
    };
    uint64_t flags = fuchsia_io_Flags_PROTOCOL_SERVICE;
    fidl_table_t options = {fidl_vector_t{
        .count = 0,
        .data = reinterpret_cast<void*>(FIDL_ALLOC_PRESENT),
    }};
    zx_handle_t object = FIDL_HANDLE_PRESENT;
    uint32_t padding = 0;
  } fixed;
  std::array<char, fuchsia_debugdata_Publisher_Name.size()> path_buffer;
  const std::byte padding[FIDL_ALIGN(fuchsia_debugdata_Publisher_Name.size()) -
                          fuchsia_debugdata_Publisher_Name.size()] = {};
};

struct alignas(FIDL_ALIGNMENT) fuchsia_debugdata_PublisherPublishRequestMessage {
  size_t size_bytes() const { return FIDL_ALIGN(sizeof(fixed) + fixed.data_sink.size); }

  struct alignas(FIDL_ALIGNMENT) {
    fidl_message_header_t hdr;
    fidl_string_t data_sink;
    zx_handle_t data;
    zx_handle_t vmo_token;
  } fixed;
  std::array<char, fuchsia_io_MAX_NAME_LENGTH> data_sink_buffer{};
  const std::byte padding[FIDL_ALIGN(fuchsia_io_MAX_NAME_LENGTH) - fuchsia_io_MAX_NAME_LENGTH] = {};
};

struct alignas(FIDL_ALIGNMENT) fuchsia_unknown_CloneableCloneRequest {
  static constexpr size_t size_bytes() { return sizeof(fuchsia_unknown_CloneableCloneRequest); }

  fidl_message_header_t hdr = TxnHeader(fuchsia_unknown_CloneableClone_Ordinal);
  zx_handle_t request = FIDL_HANDLE_PRESENT;
  uint32_t padding = 0;
};

template <class Request, size_t N>
zx::result<> SendMessage(zx::unowned_channel client_end, const Request& request,
                         const std::array<zx_handle_t, N>& handles)
  requires std::has_unique_object_representations_v<Request>
{
  const uint32_t nbytes = static_cast<uint32_t>(request.size_bytes());
  const uint32_t nhandles = static_cast<uint32_t>(handles.size());
  return zx::make_result(client_end->write(0u, &request, nbytes, handles.data(), nhandles));
}

zx::result<> fuchsia_io_DirectoryOpen_fuchsia_debugdata_Publisher(zx::unowned_channel client_end,
                                                                  zx::channel server_end) {
  return SendMessage(client_end->borrow(), fuchsia_io_DirectoryOpenRequestForDebugdata{},
                     std::array{server_end.release()});
}

zx::result<> fuchsia_debugdata_PublisherPublish(zx::unowned_channel client_end,
                                                std::string_view data_sink, zx::vmo data,
                                                zx::eventpair vmo_token) {
  fuchsia_debugdata_PublisherPublishRequestMessage request = {
      .fixed = {
          .hdr = TxnHeader(fuchsia_debugdata_PublisherPublish_Ordinal),
          .data_sink =
              {
                  .size = data_sink.size(),
                  .data = reinterpret_cast<char*>(FIDL_ALLOC_PRESENT),
              },
          .data = FIDL_HANDLE_PRESENT,
          .vmo_token = FIDL_HANDLE_PRESENT,
      }};
  if (data_sink.size() > request.data_sink_buffer.size()) [[unlikely]] {
    return zx::error{ZX_ERR_INVALID_ARGS};
  }
  data_sink.copy(request.data_sink_buffer.data(), request.data_sink_buffer.size());
  return SendMessage(client_end->borrow(), request,
                     std::array{data.release(), vmo_token.release()});
}

zx::result<> fuchsia_unknown_CloneableClone(zx::unowned_channel client_end,
                                            zx::channel server_end) {
  return SendMessage(client_end->borrow(), fuchsia_unknown_CloneableCloneRequest{},
                     std::array{server_end.release()});
}

}  // namespace

zx::result<zx::eventpair> Debugdata::Publish(zx::unowned_channel svc_client_end) && {
  zx::channel debugdata_client_end, debugdata_server_end;
  if (zx_status_t status = zx::channel::create(0, &debugdata_client_end, &debugdata_server_end);
      status != ZX_OK) [[unlikely]] {
    return zx::error{status};
  }

  zx::eventpair vmo_token_client, vmo_token_server;
  if (zx_status_t status = zx::eventpair::create(0, &vmo_token_client, &vmo_token_server);
      status != ZX_OK) {
    return zx::error{status};
  }

  if (zx::result result = fuchsia_debugdata_PublisherPublish(
          debugdata_client_end.borrow(), data_sink_, std::move(data_), std::move(vmo_token_server));
      result.is_error()) [[unlikely]] {
    return result.take_error();
  }

  if (zx::result result = fuchsia_io_DirectoryOpen_fuchsia_debugdata_Publisher(
          svc_client_end->borrow(), std::move(debugdata_server_end));
      result.is_error()) {
    return result.take_error();
  }

  return zx::ok(std::move(vmo_token_client));
}

zx::result<Debugdata::Deferred> Debugdata::DeferredPublish() && {
  zx::channel svc_client_end, svc_server_end;
  if (zx_status_t status = zx::channel::create(0, &svc_client_end, &svc_server_end);
      status != ZX_OK) [[unlikely]] {
    return zx::error{status};
  }

  zx::result token = std::move(*this).Publish(svc_client_end.borrow());
  if (token.is_error()) [[unlikely]] {
    return token.take_error();
  }

  return zx::ok(Deferred{
      .vmo_token = *std::move(token),
      .svc_server_end = std::move(svc_server_end),
  });
}

zx::result<> Debugdata::Forward(zx::unowned_channel svc_client_end, zx::channel svc_server_end) {
  return fuchsia_unknown_CloneableClone(std::move(svc_client_end), std::move(svc_server_end));
}

}  // namespace ld
