// Copyright 2021 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 "src/sys/fuzzing/framework/engine/corpus.h"

#include <lib/async/dispatcher.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/syscalls.h>

#include <algorithm>

#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"

namespace fuzzing {

// Public methods

Corpus::Corpus() { inputs_.emplace_back(); }

Corpus& Corpus::operator=(Corpus&& other) noexcept {
  options_ = other.options_;
  other.options_ = nullptr;
  prng_ = other.prng_;
  inputs_ = std::move(other.inputs_);
  total_size_ = other.total_size_;
  other.total_size_ = 0;
  return *this;
}

void Corpus::AddDefaults(Options* options) {
  if (!options->has_seed()) {
    options->set_seed(kDefaultSeed);
  }
  if (!options->has_max_input_size()) {
    options->set_max_input_size(kDefaultMaxInputSize);
  }
}

void Corpus::Configure(const OptionsPtr& options) {
  options_ = options;
  prng_.seed(options_->seed());
}

zx_status_t Corpus::LoadAt(const std::string& root, const std::vector<std::string>& dirs) {
  for (const auto& dirname : dirs) {
    auto status = ReadDir(files::JoinPath(root, dirname));
    if (status != ZX_OK) {
      return status;
    }
  }
  return ZX_OK;
}

zx_status_t Corpus::Load(const std::vector<std::string>& dirs) { return LoadAt("/pkg", dirs); }

zx_status_t Corpus::ReadDir(const std::string& dirname) {
  std::vector<std::string> contents;
  if (!files::ReadDirContents(dirname, &contents)) {
    FX_LOGS(ERROR) << "No such corpus directory: " << dirname << " (errno=" << errno << ")";
    return ZX_ERR_NOT_FOUND;
  }
  for (const auto& dir_entry : contents) {
    if (dir_entry == ".") {
      continue;
    }
    auto pathname = files::SimplifyPath(files::JoinPath(dirname, dir_entry));
    zx_status_t status = ZX_OK;
    if (files::IsFile(pathname)) {
      status = ReadFile(pathname);
    } else if (files::IsDirectory(pathname)) {
      status = ReadDir(pathname);
    }
    if (status != ZX_OK) {
      return status;
    }
  }
  return ZX_OK;
}

zx_status_t Corpus::ReadFile(const std::string& filename) {
  std::vector<uint8_t> input;
  if (!files::ReadFileToVector(filename, &input)) {
    FX_LOGS(ERROR) << "Failed to read " << filename;
    return ZX_ERR_IO;
  }
  return Add(Input(input));
}

zx_status_t Corpus::Add(Input input) {
  FX_DCHECK(options_);
  if (input.size() > options_->max_input_size()) {
    return ZX_ERR_BUFFER_TOO_SMALL;
  }
  // Keep the inputs sorted and deduplicated.
  auto iter = std::lower_bound(inputs_.begin(), inputs_.end(), input);
  if (iter == inputs_.end() || *iter != input) {
    total_size_ += input.size();
    inputs_.insert(iter, std::move(input));
  }
  return ZX_OK;
}

zx_status_t Corpus::Add(CorpusPtr corpus) {
  if (!corpus) {
    return ZX_ERR_INVALID_ARGS;
  }
  for (auto& input : corpus->inputs_) {
    if (auto status = Add(input.Duplicate()); status != ZX_OK) {
      return status;
    }
  }
  return ZX_OK;
}

bool Corpus::At(size_t offset, Input* out) {
  out->Clear();
  if (offset >= inputs_.size()) {
    return false;
  }
  out->Duplicate(inputs_[offset]);
  return true;
}

void Corpus::Pick(Input* out) {
  // Use rejection sampling to get uniform distribution.
  // NOLINTNEXTLINE(google-runtime-int)
  static_assert(sizeof(unsigned long long) * 8 == 64);
  uint64_t size = inputs_.size();
  FX_DCHECK(size > 0);
  auto shift = 64 - __builtin_clzll(size);
  FX_DCHECK(size < 64);
  auto mod = 1ULL << shift;
  size_t offset;
  do {
    offset = prng_() % mod;
  } while (offset >= size);
  out->Duplicate(inputs_[offset]);
}

}  // namespace fuzzing
