// 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/txn_header.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <zircon/fidl.h>
#include <zircon/process.h>
#include <zircon/sanitizer.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/log.h>

#include <iterator>
#include <vector>

#include "fuchsia-io-constants.h"

__attribute__((visibility("hidden"))) zx_handle_t __zircon_namespace_svc = ZX_HANDLE_INVALID;

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

constexpr const char fuchsia_debugdata_Publisher_Name[] = "fuchsia.debugdata.Publisher";
constexpr uint64_t fuchsia_debugdata_PublisherPublishOrdinal = 0xF52F8806121E066;

struct fuchsia_debugdata_PublisherPublishRequestMessage {
  FIDL_ALIGNDECL
  fidl_message_header_t hdr;
  fidl_string_t data_sink;
  zx_handle_t data;
  zx_handle_t vmo_token;
};

#if __has_feature(address_sanitizer)
[[clang::no_sanitize("address")]]
#endif
zx_status_t
_fuchsia_io_DirectoryOpen(zx_handle_t channel, uint32_t flags, uint32_t mode, const char* path_data,
                          size_t path_size, zx_handle_t object) {
  if (path_size > fuchsia_io_MAX_PATH_LENGTH) {
    _zx_handle_close(object);
    return ZX_ERR_INVALID_ARGS;
  }
  FIDL_ALIGNDECL char
      wr_bytes[sizeof(fuchsia_io_DirectoryOpenRequest) + fuchsia_io_MAX_PATH_LENGTH] = {};
  fuchsia_io_DirectoryOpenRequest* request = (fuchsia_io_DirectoryOpenRequest*)wr_bytes;
  fidl_init_txn_header(&request->hdr, 0, fuchsia_io_DirectoryOpenOrdinal, 0);
  request->flags = flags;
  request->mode = mode;
  request->path.data = (char*)FIDL_ALLOC_PRESENT;
  request->path.size = path_size;
  request->object = FIDL_HANDLE_PRESENT;
  memcpy(&wr_bytes[sizeof(*request)], path_data, path_size);
  return _zx_channel_write(
      channel, 0u, wr_bytes,
      static_cast<uint32_t>(sizeof(fuchsia_io_DirectoryOpenRequest) + FIDL_ALIGN(path_size)),
      &object, 1);
}

#if __has_feature(address_sanitizer)
[[clang::no_sanitize("address")]]
#endif
zx_status_t
_fuchsia_debugdata_PublisherPublish(zx_handle_t debug_data_channel, const char* data_sink_data,
                                    size_t data_sink_size, zx_handle_t data,
                                    zx_handle_t vmo_token) {
  if (data_sink_size > fuchsia_io_MAX_NAME_LENGTH) {
    _zx_handle_close(data);
    return ZX_ERR_INVALID_ARGS;
  }
  FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_debugdata_PublisherPublishRequestMessage) +
                               fuchsia_io_MAX_NAME_LENGTH] = {};
  fuchsia_debugdata_PublisherPublishRequestMessage* request =
      (fuchsia_debugdata_PublisherPublishRequestMessage*)wr_bytes;
  fidl_init_txn_header(&request->hdr, 0, fuchsia_debugdata_PublisherPublishOrdinal, 0);
  request->data_sink.data = (char*)FIDL_ALLOC_PRESENT;
  request->data_sink.size = data_sink_size;
  request->data = FIDL_HANDLE_PRESENT;
  request->vmo_token = FIDL_HANDLE_PRESENT;

  zx_handle_t handles[2] = {data, vmo_token};

  memcpy(&wr_bytes[sizeof(*request)], data_sink_data, data_sink_size);
  return _zx_channel_write(
      debug_data_channel, 0u, wr_bytes,
      static_cast<uint32_t>(sizeof(fuchsia_debugdata_PublisherPublishRequestMessage) +
                            FIDL_ALIGN(data_sink_size)),
      handles, std::size(handles));
}

zx_handle_t sanitizer_debugdata_connect() {
  zx_handle_t h0, h1;
  zx_status_t status;

  if ((status = _zx_channel_create(0, &h0, &h1)) != ZX_OK) {
    constexpr const char kErrorChannelCreate[] = "Failed to create channel for debugdata service";
    __sanitizer_log_write(kErrorChannelCreate, sizeof(kErrorChannelCreate) - 1);
    return ZX_HANDLE_INVALID;
  }

  status = _fuchsia_io_DirectoryOpen(__zircon_namespace_svc, 0, 0, fuchsia_debugdata_Publisher_Name,
                                     sizeof(fuchsia_debugdata_Publisher_Name) - 1, h0);
  if (status != ZX_OK) {
    constexpr const char kErrorDirectoryOpen[] = "Failed to open service namespace";
    __sanitizer_log_write(kErrorDirectoryOpen, sizeof(kErrorDirectoryOpen) - 1);
    _zx_handle_close(h1);
    return ZX_HANDLE_INVALID;
  }

  return h1;
}

}  // namespace

// Publish VMO and return back event pair handle which controls the lifetime of
// the VMO.
__EXPORT
zx_handle_t __sanitizer_publish_data(const char* sink_name, zx_handle_t vmo) {
  if (__zircon_namespace_svc == ZX_HANDLE_INVALID) {
    _zx_handle_close(vmo);
    return ZX_HANDLE_INVALID;
  }

  zx_handle_t vmo_token_client, vmo_token_server;
  if (_zx_eventpair_create(0, &vmo_token_client, &vmo_token_server) != ZX_OK) {
    constexpr char kErrorEventPairCreate[] = "Failed to create eventpair for debugdata VMO token";
    __sanitizer_log_write(kErrorEventPairCreate, sizeof(kErrorEventPairCreate) - 1);
    return ZX_HANDLE_INVALID;
  }

  zx_handle_t debugdata_channel = sanitizer_debugdata_connect();
  zx_status_t status = _fuchsia_debugdata_PublisherPublish(
      debugdata_channel, sink_name, strlen(sink_name), vmo, vmo_token_server);
  _zx_handle_close(debugdata_channel);

  if (status != ZX_OK) {
    constexpr const char kErrorPublish[] = "Failed to publish data";
    __sanitizer_log_write(kErrorPublish, sizeof(kErrorPublish) - 1);
    _zx_handle_close(vmo_token_client);
    return ZX_HANDLE_INVALID;
  }

  return vmo_token_client;
}
