//===-- xray_log_interface.cc ---------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of XRay, a function call tracing system.
//
//===----------------------------------------------------------------------===//
#include "xray/xray_log_interface.h"

#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_mutex.h"
#include "xray/xray_interface.h"
#include "xray_defs.h"

namespace __xray {
static SpinMutex XRayImplMutex;
static XRayLogImpl CurrentXRayImpl{nullptr, nullptr, nullptr, nullptr};
static XRayLogImpl *GlobalXRayImpl = nullptr;

// This is the default implementation of a buffer iterator, which always yields
// a null buffer.
XRayBuffer NullBufferIterator(XRayBuffer) XRAY_NEVER_INSTRUMENT {
  return {nullptr, 0};
}

// This is the global function responsible for iterating through given buffers.
atomic_uintptr_t XRayBufferIterator{
    reinterpret_cast<uintptr_t>(&NullBufferIterator)};

// We use a linked list of Mode to XRayLogImpl mappings. This is a linked list
// when it should be a map because we're avoiding having to depend on C++
// standard library data structures at this level of the implementation.
struct ModeImpl {
  ModeImpl *Next;
  const char *Mode;
  XRayLogImpl Impl;
};

static ModeImpl SentinelModeImpl{
    nullptr, nullptr, {nullptr, nullptr, nullptr, nullptr}};
static ModeImpl *ModeImpls = &SentinelModeImpl;
static const ModeImpl *CurrentMode = nullptr;

} // namespace __xray

using namespace __xray;

void __xray_log_set_buffer_iterator(XRayBuffer (*Iterator)(XRayBuffer))
    XRAY_NEVER_INSTRUMENT {
  atomic_store(&__xray::XRayBufferIterator,
               reinterpret_cast<uintptr_t>(Iterator), memory_order_release);
}

void __xray_log_remove_buffer_iterator() XRAY_NEVER_INSTRUMENT {
  __xray_log_set_buffer_iterator(&NullBufferIterator);
}

XRayLogRegisterStatus
__xray_log_register_mode(const char *Mode,
                         XRayLogImpl Impl) XRAY_NEVER_INSTRUMENT {
  if (Impl.flush_log == nullptr || Impl.handle_arg0 == nullptr ||
      Impl.log_finalize == nullptr || Impl.log_init == nullptr)
    return XRayLogRegisterStatus::XRAY_INCOMPLETE_IMPL;

  SpinMutexLock Guard(&XRayImplMutex);
  // First, look for whether the mode already has a registered implementation.
  for (ModeImpl *it = ModeImpls; it != &SentinelModeImpl; it = it->Next) {
    if (!internal_strcmp(Mode, it->Mode))
      return XRayLogRegisterStatus::XRAY_DUPLICATE_MODE;
  }
  auto *NewModeImpl = static_cast<ModeImpl *>(InternalAlloc(sizeof(ModeImpl)));
  NewModeImpl->Next = ModeImpls;
  NewModeImpl->Mode = internal_strdup(Mode);
  NewModeImpl->Impl = Impl;
  ModeImpls = NewModeImpl;
  return XRayLogRegisterStatus::XRAY_REGISTRATION_OK;
}

XRayLogRegisterStatus
__xray_log_select_mode(const char *Mode) XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayImplMutex);
  for (ModeImpl *it = ModeImpls; it != &SentinelModeImpl; it = it->Next) {
    if (!internal_strcmp(Mode, it->Mode)) {
      CurrentMode = it;
      CurrentXRayImpl = it->Impl;
      GlobalXRayImpl = &CurrentXRayImpl;
      __xray_set_handler(it->Impl.handle_arg0);
      return XRayLogRegisterStatus::XRAY_REGISTRATION_OK;
    }
  }
  return XRayLogRegisterStatus::XRAY_MODE_NOT_FOUND;
}

const char *__xray_log_get_current_mode() XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayImplMutex);
  if (CurrentMode != nullptr)
    return CurrentMode->Mode;
  return nullptr;
}

void __xray_set_log_impl(XRayLogImpl Impl) XRAY_NEVER_INSTRUMENT {
  if (Impl.log_init == nullptr || Impl.log_finalize == nullptr ||
      Impl.handle_arg0 == nullptr || Impl.flush_log == nullptr) {
    SpinMutexLock Guard(&XRayImplMutex);
    GlobalXRayImpl = nullptr;
    CurrentMode = nullptr;
    __xray_remove_handler();
    __xray_remove_handler_arg1();
    return;
  }

  SpinMutexLock Guard(&XRayImplMutex);
  CurrentXRayImpl = Impl;
  GlobalXRayImpl = &CurrentXRayImpl;
  __xray_set_handler(Impl.handle_arg0);
}

void __xray_remove_log_impl() XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayImplMutex);
  GlobalXRayImpl = nullptr;
  __xray_remove_handler();
  __xray_remove_handler_arg1();
}

XRayLogInitStatus __xray_log_init(size_t BufferSize, size_t MaxBuffers,
                                  void *Args,
                                  size_t ArgsSize) XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayImplMutex);
  if (!GlobalXRayImpl)
    return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
  return GlobalXRayImpl->log_init(BufferSize, MaxBuffers, Args, ArgsSize);
}

XRayLogInitStatus __xray_log_init_mode(const char *Mode, const char *Config)
    XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayImplMutex);
  if (!GlobalXRayImpl)
    return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;

  if (Config == nullptr)
    return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;

  // Check first whether the current mode is the same as what we expect.
  if (CurrentMode == nullptr || internal_strcmp(CurrentMode->Mode, Mode) != 0)
    return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;

  // Here we do some work to coerce the pointer we're provided, so that
  // the implementations that still take void* pointers can handle the
  // data provided in the Config argument.
  return GlobalXRayImpl->log_init(
      0, 0, const_cast<void *>(static_cast<const void *>(Config)), 0);
}

XRayLogInitStatus
__xray_log_init_mode_bin(const char *Mode, const char *Config,
                         size_t ConfigSize) XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayImplMutex);
  if (!GlobalXRayImpl)
    return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;

  if (Config == nullptr)
    return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;

  // Check first whether the current mode is the same as what we expect.
  if (CurrentMode == nullptr || internal_strcmp(CurrentMode->Mode, Mode) != 0)
    return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;

  // Here we do some work to coerce the pointer we're provided, so that
  // the implementations that still take void* pointers can handle the
  // data provided in the Config argument.
  return GlobalXRayImpl->log_init(
      0, 0, const_cast<void *>(static_cast<const void *>(Config)), ConfigSize);
}

XRayLogInitStatus __xray_log_finalize() XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayImplMutex);
  if (!GlobalXRayImpl)
    return XRayLogInitStatus::XRAY_LOG_UNINITIALIZED;
  return GlobalXRayImpl->log_finalize();
}

XRayLogFlushStatus __xray_log_flushLog() XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayImplMutex);
  if (!GlobalXRayImpl)
    return XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING;
  return GlobalXRayImpl->flush_log();
}

XRayLogFlushStatus __xray_log_process_buffers(
    void (*Processor)(const char *, XRayBuffer)) XRAY_NEVER_INSTRUMENT {
  // We want to make sure that there will be no changes to the global state for
  // the log by synchronising on the XRayBufferIteratorMutex.
  if (!GlobalXRayImpl)
    return XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING;
  auto Iterator = reinterpret_cast<XRayBuffer (*)(XRayBuffer)>(
      atomic_load(&XRayBufferIterator, memory_order_acquire));
  auto Buffer = (*Iterator)(XRayBuffer{nullptr, 0});
  auto Mode = CurrentMode ? CurrentMode->Mode : nullptr;
  while (Buffer.Data != nullptr) {
    (*Processor)(Mode, Buffer);
    Buffer = (*Iterator)(Buffer);
  }
  return XRayLogFlushStatus::XRAY_LOG_FLUSHED;
}
