// Copyright 2017 The Chromium 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 <chrono>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>

#include "base/logging.h"
#include "v8/include/libplatform/libplatform.h"
#include "v8/include/v8.h"

using v8::MaybeLocal;
using std::ref;
using std::lock_guard;
using std::mutex;
using std::chrono::time_point;
using std::chrono::steady_clock;
using std::chrono::seconds;
using std::chrono::duration_cast;

static const seconds kSleepSeconds(1);

// Because of the sleep we do, the actual max will be:
// kSleepSeconds + kMaxExecutionSeconds.
// TODO(metzman): Determine if having such a short timeout causes too much
// indeterminism.
static const seconds kMaxExecutionSeconds(7);

// Inspired by/copied from d8 code, this allocator will return nullptr when
// an allocation request is made that puts currently_allocated_ over
// kAllocationLimit (1 GB). Should handle the current allocations done by V8.
class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
  std::unique_ptr<Allocator> allocator_ =
      std::unique_ptr<Allocator>(NewDefaultAllocator());

  const size_t kAllocationLimit = 1000 * 1024 * 1024;
  // TODO(metzman): Determine if this approach where we keep track of state
  // between runs is a good idea. Maybe we should simply prevent allocations
  // over a certain size regardless of previous allocations.
  size_t currently_allocated_;
  mutex mtx_;

 public:
  MockArrayBufferAllocator()
      : v8::ArrayBuffer::Allocator(), currently_allocated_(0) {}

  void* Allocate(size_t length) override {
    void* data = AllocateUninitialized(length);
    return data == nullptr ? data : memset(data, 0, length);
  }

  void* AllocateUninitialized(size_t length) override {
    lock_guard<mutex> mtx_locker(mtx_);
    if (length + currently_allocated_ > kAllocationLimit) {
      return nullptr;
    }
    currently_allocated_ += length;
    return malloc(length);
  }

  void Free(void* ptr, size_t length) override {
    lock_guard<mutex> mtx_locker(mtx_);
    currently_allocated_ -= length;
    // We need to free before we unlock, otherwise currently_allocated_ will
    // be innacurate.
    free(ptr);
  }
};

void terminate_execution(v8::Isolate* isolate,
                         mutex& mtx,
                         bool& is_running,
                         time_point<steady_clock>& start_time) {
  while (true) {
    std::this_thread::sleep_for(kSleepSeconds);
    mtx.lock();
    if (is_running) {
      if (duration_cast<seconds>(steady_clock::now() - start_time) >
          kMaxExecutionSeconds) {
        isolate->TerminateExecution();
        is_running = false;
        std::cout << "Terminated" << std::endl;
        fflush(0);
      }
    }
    mtx.unlock();
  }
}

struct Environment {
  Environment() {
    platform_ = v8::platform::NewDefaultPlatform(
        0, v8::platform::IdleTaskSupport::kDisabled,
        v8::platform::InProcessStackDumping::kDisabled, nullptr);

    v8::V8::InitializePlatform(platform_.get());
    v8::V8::Initialize();
    v8::Isolate::CreateParams create_params;

    create_params.array_buffer_allocator = &mock_arraybuffer_allocator;
    isolate = v8::Isolate::New(create_params);
    terminator_thread = std::thread(terminate_execution, isolate, ref(mtx),
                                    ref(is_running), ref(start_time));
  }
  MockArrayBufferAllocator mock_arraybuffer_allocator;
  mutex mtx;
  std::thread terminator_thread;
  v8::Isolate* isolate;
  std::unique_ptr<v8::Platform> platform_;
  time_point<steady_clock> start_time;
  bool is_running;
};

// Explicitly specify some attributes to avoid issues with the linker dead-
// stripping the following function on macOS, as it is not called directly
// by fuzz target. LibFuzzer runtime uses dlsym() to resolve that function.
extern "C" __attribute__((used)) __attribute__((visibility("default"))) int
LLVMFuzzerInitialize(int* argc, char*** argv) {
  v8::V8::InitializeICUDefaultLocation((*argv)[0]);
  v8::V8::InitializeExternalStartupData((*argv)[0]);
  v8::V8::SetFlagsFromCommandLine(argc, *argv, true);
  return 0;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  static Environment* env = new Environment();

  if (size < 1)
    return 0;

  v8::Isolate::Scope isolate_scope(env->isolate);
  v8::HandleScope handle_scope(env->isolate);
  v8::Local<v8::Context> context = v8::Context::New(env->isolate);
  v8::Context::Scope context_scope(context);

  std::string source_string =
      std::string(reinterpret_cast<const char*>(data), size);

  MaybeLocal<v8::String> source_v8_string = v8::String::NewFromUtf8(
      env->isolate, source_string.c_str(), v8::NewStringType::kNormal);

  if (source_v8_string.IsEmpty())
    return 0;

  v8::TryCatch try_catch(env->isolate);
  MaybeLocal<v8::Script> script =
      v8::Script::Compile(context, source_v8_string.ToLocalChecked());

  if (script.IsEmpty())
    return 0;

  auto local_script = script.ToLocalChecked();
  env->mtx.lock();
  env->start_time = steady_clock::now();
  env->is_running = true;
  env->mtx.unlock();

  ALLOW_UNUSED_LOCAL(local_script->Run(context));

  lock_guard<mutex> mtx_locker(env->mtx);
  env->is_running = false;
  return 0;
}
