/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "palette/palette.h"

#include <dlfcn.h>
#include <stdlib.h>

#include <android/log.h>
#include <android-base/macros.h>

namespace {

// Logging tag.
static constexpr const char* kLogTag = "libartpalette";

// Name of the palette library present in the /system partition.
static constexpr const char* kPaletteSystemLibrary = "libartpalette-system.so";

// Generic method used when a dynamically loaded palette instance does not
// support a method.
palette_status_t PaletteMethodNotSupported() {
  return PALETTE_STATUS_NOT_SUPPORTED;
}

// Declare type aliases for pointers to each function in the interface.
#define PALETTE_METHOD_TYPE_ALIAS(Name, ...) \
  using Name ## Method = palette_status_t(*)(__VA_ARGS__);
PALETTE_METHOD_LIST(PALETTE_METHOD_TYPE_ALIAS)
#undef PALETTE_METHOD_TYPE_ALIAS

// Singleton class responsible for dynamically loading the palette library and
// binding functions there to method pointers.
class PaletteLoader {
 public:
  static PaletteLoader& Instance() {
    static PaletteLoader instance;
    return instance;
  }

  // Accessor methods to get instances of palette methods.
#define PALETTE_LOADER_METHOD_ACCESSOR(Name, ...)                       \
  Name ## Method Get ## Name ## Method() const { return Name ## Method ## _; }
PALETTE_METHOD_LIST(PALETTE_LOADER_METHOD_ACCESSOR)
#undef PALETTE_LOADER_METHOD_ACCESSOR

 private:
  PaletteLoader();

  static void* OpenLibrary();
  static void* GetMethod(void* palette_lib, const char* name);

  // Handle to the palette library from dlopen().
  void* palette_lib_;

  // Fields to store pointers to palette methods.
#define PALETTE_LOADER_METHOD_FIELD(Name, ...) \
  const Name ## Method Name ## Method ## _;
  PALETTE_METHOD_LIST(PALETTE_LOADER_METHOD_FIELD)
#undef PALETTE_LOADER_METHOD_FIELD

  DISALLOW_COPY_AND_ASSIGN(PaletteLoader);
};

void* PaletteLoader::OpenLibrary() {
  void* handle = dlopen(kPaletteSystemLibrary, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
  if (handle == nullptr) {
    // dlerror message includes details of error and file being opened.
    __android_log_assert(nullptr, kLogTag, "%s", dlerror());
  }
  return handle;
}

void* PaletteLoader::GetMethod(void* palette_lib, const char* name) {
  void* method = nullptr;
  if (palette_lib != nullptr) {
    method = dlsym(palette_lib, name);
  }
  if (method == nullptr) {
    return reinterpret_cast<void*>(PaletteMethodNotSupported);
  }
  // TODO(oth): consider new GetMethodSignature() in the Palette API which
  // would allow checking the validity of the type signatures.
  return method;
}

PaletteLoader::PaletteLoader() :
    palette_lib_(OpenLibrary())
#define PALETTE_LOADER_BIND_METHOD(Name, ...)                           \
    , Name ## Method ## _(reinterpret_cast<Name ## Method>(GetMethod(palette_lib_, #Name)))
    PALETTE_METHOD_LIST(PALETTE_LOADER_BIND_METHOD)
#undef PALETTE_LOADER_BIND_METHOD
{
}

}  // namespace

extern "C" {

// Unless explicitly mentioned otherwise, the following methods have been
// introduced in version 1 API, corresponding to SDK level 31.

palette_status_t PaletteSchedSetPriority(int32_t tid, int32_t java_priority) {
  PaletteSchedSetPriorityMethod m = PaletteLoader::Instance().GetPaletteSchedSetPriorityMethod();
  return m(tid, java_priority);
}

palette_status_t PaletteSchedGetPriority(int32_t tid, /*out*/int32_t* java_priority) {
  PaletteSchedGetPriorityMethod m = PaletteLoader::Instance().GetPaletteSchedGetPriorityMethod();
  return m(tid, java_priority);
}

palette_status_t PaletteWriteCrashThreadStacks(/*in*/const char* stack, size_t stack_len) {
  PaletteWriteCrashThreadStacksMethod m =
      PaletteLoader::Instance().GetPaletteWriteCrashThreadStacksMethod();
  return m(stack, stack_len);
}

palette_status_t PaletteTraceEnabled(/*out*/bool* enabled) {
  PaletteTraceEnabledMethod m = PaletteLoader::Instance().GetPaletteTraceEnabledMethod();
  return m(enabled);
}

palette_status_t PaletteTraceBegin(/*in*/const char* name) {
  PaletteTraceBeginMethod m = PaletteLoader::Instance().GetPaletteTraceBeginMethod();
  return m(name);
}

palette_status_t PaletteTraceEnd() {
  PaletteTraceEndMethod m = PaletteLoader::Instance().GetPaletteTraceEndMethod();
  return m();
}

palette_status_t PaletteTraceIntegerValue(/*in*/const char* name, int32_t value) {
  PaletteTraceIntegerValueMethod m = PaletteLoader::Instance().GetPaletteTraceIntegerValueMethod();
  return m(name, value);
}

palette_status_t PaletteAshmemCreateRegion(const char* name, size_t size, int* fd) {
  PaletteAshmemCreateRegionMethod m =
      PaletteLoader::Instance().GetPaletteAshmemCreateRegionMethod();
  return m(name, size, fd);
}

palette_status_t PaletteAshmemSetProtRegion(int fd, int prot) {
  PaletteAshmemSetProtRegionMethod m =
      PaletteLoader::Instance().GetPaletteAshmemSetProtRegionMethod();
  return m(fd, prot);
}

palette_status_t PaletteCreateOdrefreshStagingDirectory(const char** staging_dir) {
  PaletteCreateOdrefreshStagingDirectoryMethod m =
      PaletteLoader::Instance().GetPaletteCreateOdrefreshStagingDirectoryMethod();
  return m(staging_dir);
}

palette_status_t PaletteShouldReportDex2oatCompilation(bool* value) {
  PaletteShouldReportDex2oatCompilationMethod m =
      PaletteLoader::Instance().GetPaletteShouldReportDex2oatCompilationMethod();
  return m(value);
}

palette_status_t PaletteNotifyStartDex2oatCompilation(int source_fd,
                                                      int art_fd,
                                                      int oat_fd,
                                                      int vdex_fd) {
  PaletteNotifyStartDex2oatCompilationMethod m =
      PaletteLoader::Instance().GetPaletteNotifyStartDex2oatCompilationMethod();
  return m(source_fd, art_fd, oat_fd, vdex_fd);
}

palette_status_t PaletteNotifyEndDex2oatCompilation(int source_fd,
                                                    int art_fd,
                                                    int oat_fd,
                                                    int vdex_fd) {
  PaletteNotifyEndDex2oatCompilationMethod m =
      PaletteLoader::Instance().GetPaletteNotifyEndDex2oatCompilationMethod();
  return m(source_fd, art_fd, oat_fd, vdex_fd);
}

palette_status_t PaletteNotifyDexFileLoaded(const char* path) {
  PaletteNotifyDexFileLoadedMethod m =
      PaletteLoader::Instance().GetPaletteNotifyDexFileLoadedMethod();
  return m(path);
}

palette_status_t PaletteNotifyOatFileLoaded(const char* path) {
  PaletteNotifyOatFileLoadedMethod m =
      PaletteLoader::Instance().GetPaletteNotifyOatFileLoadedMethod();
  return m(path);
}

palette_status_t PaletteShouldReportJniInvocations(bool* value) {
  PaletteShouldReportJniInvocationsMethod m =
      PaletteLoader::Instance().GetPaletteShouldReportJniInvocationsMethod();
  return m(value);
}

palette_status_t PaletteNotifyBeginJniInvocation(JNIEnv* env) {
  PaletteNotifyBeginJniInvocationMethod m =
      PaletteLoader::Instance().GetPaletteNotifyBeginJniInvocationMethod();
  return m(env);
}

palette_status_t PaletteNotifyEndJniInvocation(JNIEnv* env) {
  PaletteNotifyEndJniInvocationMethod m =
      PaletteLoader::Instance().GetPaletteNotifyEndJniInvocationMethod();
  return m(env);
}

// Introduced in version 2 API, corresponding to SDK level 33.
palette_status_t PaletteReportLockContention(JNIEnv* env,
                                             int32_t wait_ms,
                                             const char* filename,
                                             int32_t line_number,
                                             const char* method_name,
                                             const char* owner_filename,
                                             int32_t owner_line_number,
                                             const char* owner_method_name,
                                             const char* proc_name,
                                             const char* thread_name) {
  PaletteReportLockContentionMethod m =
      PaletteLoader::Instance().GetPaletteReportLockContentionMethod();
  return m(env,
           wait_ms,
           filename,
           line_number,
           method_name,
           owner_filename,
           owner_line_number,
           owner_method_name,
           proc_name,
           thread_name);
}

// Introduced in version 3 API, corresponding to SDK level 34.
palette_status_t PaletteSetTaskProfiles(int32_t tid,
                                        const char* const profiles[],
                                        size_t profiles_len) {
  PaletteSetTaskProfilesMethod m = PaletteLoader::Instance().GetPaletteSetTaskProfilesMethod();
  return m(tid, profiles, profiles_len);
}

}  // extern "C"
