// 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.

#ifndef SRC_SYS_FUZZING_COMMON_INPUT_H_
#define SRC_SYS_FUZZING_COMMON_INPUT_H_

#include <fuchsia/fuzzer/cpp/fidl.h>
#include <limits.h>
#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <string>

#include "src/lib/fxl/macros.h"
#include "src/sys/fuzzing/common/shared-memory.h"

namespace fuzzing {

using FidlInput = ::fuchsia::fuzzer::Input;

// Represents a single fuzzing input. A corpus is a collection of fuzzing inputs. Inputs are either
// provided as part of a seed corpus, or generated by mutating existing inputs.
class Input final {
 public:
  Input() = default;
  Input(const std::initializer_list<uint8_t>& bytes) : Input(std::vector<uint8_t>(bytes)) {}
  explicit Input(const std::vector<uint8_t>& bytes) : Input(bytes.data(), bytes.size()) {}
  explicit Input(const std::string& bytes) : Input(bytes.c_str(), bytes.size()) {}
  explicit Input(SharedMemory& shmem);
  explicit Input(size_t size) : Input(std::vector<uint8_t>(size)) {}
  Input(Input&& other) noexcept { *this = std::move(other); }

  ~Input() = default;

  Input& operator=(Input&& other) noexcept;
  inline bool operator==(const Input& other) const { return Compare(other) == 0; }
  inline bool operator!=(const Input& other) const { return Compare(other) != 0; }
  inline bool operator<(const Input& other) const { return Compare(other) < 0; }
  inline bool operator>(const Input& other) const { return Compare(other) > 0; }
  inline bool operator<=(const Input& other) const { return Compare(other) <= 0; }
  inline bool operator>=(const Input& other) const { return Compare(other) >= 0; }

  // This method allows easier printing by gTest.
  friend std::ostream& operator<<(std::ostream& os, const Input& input) {
    return os << input.ToHex(/* truncate */ false);
  }

  const uint8_t* data() const { return data_.get(); }
  uint8_t* data() { return data_.get(); }
  size_t size() const { return size_; }
  size_t capacity() const { return capacity_; }
  size_t num_features() const { return num_features_; }

  void set_num_features(size_t num_features) { num_features_ = num_features; }

  // Returns a hex string representation. If the input is more than 6 bytes and |truncate|d, the
  // returned string will be the first few bytes, followed by "...".
  std::string ToHex(bool truncate = true) const;

  // Exchanges the internal state of this input with another.
  void Swap(Input& other);

  // Creates a copy of this input.
  Input Duplicate() const;

  // Makes this object a copy of the |other|.
  void Duplicate(const Input& other);

  // Ensures the input has at least the given |capacity|.
  void Reserve(size_t capacity);

  // Appends data to this input. The input must have sufficient remaining capacity for |size| bytes.
  void Write(const void* data, size_t size);
  void Write(uint8_t one_byte);

  // Reserves capacity and sets the size of this input to |size| bytes. This method does NOT
  // initialize the data, but can be used in conjunction with the |data()| accessor to write into
  // the input. Returns the new size.
  size_t Resize(size_t size);

  // Truncates the input if larger than |max_size|. Returns the new size.
  size_t Truncate(size_t max_size);

  // Reduces the capacity of this input to its size. Returns the new size.
  size_t ShrinkToFit();

  // Removes all data from this input.
  void Clear();

 private:
  Input(const void* data, size_t size) { Allocate(size, data, size); }

  void Allocate(size_t capacity, const void* data = nullptr, size_t size = 0);

  void StartExport(zx::socket* sender, FidlInput* receiver) const;
  void FinishExport(const zx::socket& sender) const;

  // Compares this input to some |other| input, and returns negative, zero, or positive depending on
  // whether this input should be considered less than, equal to, or greater than the other input
  // when sorting. The defined sort order is "smaller size, then more features, then byte-by-byte".
  //
  // Returns negative if this input is shorter than |other|, or the same length but with more
  // features than |other|, or the same length with the same number of features but the first
  // non-matching byte is less than the corresponding byte in |other|.
  //
  // Returns postive if this input is longer than |other|, or the same length but with fewer
  // features than |other|, or the same length with the same number of features but the first
  // non-matching byte is greater than the corresponding byte in |other|.
  //
  // Returns zero if this input has the same bytes as |other|.
  int Compare(const Input& other) const;

  std::unique_ptr<uint8_t[]> data_;
  size_t capacity_ = 0;
  size_t size_ = 0;
  size_t num_features_ = 0;

  FXL_DISALLOW_COPY_AND_ASSIGN(Input);
};

}  // namespace fuzzing

#endif  // SRC_SYS_FUZZING_COMMON_INPUT_H_
