// Copyright 2016 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 PERIDOT_LIB_CONVERT_CONVERT_H_
#define PERIDOT_LIB_CONVERT_CONVERT_H_

#include <string>

#include <flatbuffers/flatbuffers.h>
#include <leveldb/db.h>
#include <lib/fidl/cpp/array.h>
#include <lib/fidl/cpp/vector.h>
#include <lib/fxl/strings/string_view.h>
#include <rapidjson/document.h>

namespace convert {

// Provides conversions between fidl::VectorPtr, leveldb::Slice and std::string
// representations of a data object.
//
// This class doesn't take ownership of the data used to construct it. The data
// must outlive it. It is used to allow transparent handling of FIDL arrays,
// leveldb slices and strings.
//
// Single-argument constructors and conversion operators are marked as NOLINT to
// suppress `google-explicit-constructor` clang-tidy warning - in this case the
// implicit conversion is intended.
class ExtendedStringView : public fxl::StringView {
 public:
  ExtendedStringView(const std::vector<uint8_t>& array)  // NOLINT
      : fxl::StringView(reinterpret_cast<const char*>(array.data()),
                        array.size()) {}
  ExtendedStringView(const fidl::VectorPtr<uint8_t>& array)  // NOLINT
      : fxl::StringView(reinterpret_cast<const char*>(array->data()),
                        array->size()) {}
  template <size_t N>
  constexpr ExtendedStringView(const fidl::Array<uint8_t, N>& array)  // NOLINT
      : fxl::StringView(reinterpret_cast<const char*>(array.data()), N) {}
  ExtendedStringView(const leveldb::Slice& slice)  // NOLINT
      : fxl::StringView(slice.data(), slice.size()) {}
  ExtendedStringView(const std::string& string)  // NOLINT
      : fxl::StringView(string) {}
  constexpr ExtendedStringView(fxl::StringView string_view)  // NOLINT
      : fxl::StringView(string_view) {}
  ExtendedStringView(const rapidjson::Value& value)  // NOLINT
      : fxl::StringView(value.GetString(), value.GetStringLength()) {
    FXL_DCHECK(value.IsString());
  }
  template <size_t N>
  constexpr ExtendedStringView(const char (&str)[N])  // NOLINT
      : fxl::StringView(str) {}
  ExtendedStringView(  // NOLINT
      const flatbuffers::Vector<uint8_t>* byte_storage)
      : fxl::StringView(reinterpret_cast<const char*>(byte_storage->data()),
                        byte_storage->size()) {}
  ExtendedStringView(  // NOLINT
      const flatbuffers::FlatBufferBuilder& buffer_builder)
      : fxl::StringView(
            reinterpret_cast<char*>(buffer_builder.GetBufferPointer()),
            buffer_builder.GetSize()) {}

  operator leveldb::Slice() const {  // NOLINT
    return leveldb::Slice(data(), size());
  }

  std::vector<uint8_t> ToArray();

  flatbuffers::Offset<flatbuffers::Vector<uint8_t>> ToFlatBufferVector(
      flatbuffers::FlatBufferBuilder* builder);

  std::string ToHex();
};

// Returns the ExtendedStringView representation of the given value.
inline ExtendedStringView ToStringView(ExtendedStringView value) {
  return value;
}

// Returns the representation of the given value in LevelDB.
inline leveldb::Slice ToSlice(ExtendedStringView value) { return value; }

// Returns the std::vector representation of the given value.
std::vector<uint8_t> ToArray(ExtendedStringView value);

// Returns the fidl::Array representation of the given value.
template <size_t N>
void ToArray(ExtendedStringView value, fidl::Array<uint8_t, N>* out) {
  ZX_ASSERT(value.size() == N);
  memcpy(out->mutable_data(), value.data(), N);
}

// Returns the std::string representation of the given value.
std::string ToString(ExtendedStringView value);

// Returns the hexadecimal representation of the given value.
std::string ToHex(ExtendedStringView value);

// Store the given value as a FlatBufferVector in the given builder.
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> ToFlatBufferVector(
    flatbuffers::FlatBufferBuilder* builder, ExtendedStringView value);

// Comparator that allows heterogeneous lookup by StringView and
// std::string in a container with the key type of std::string.
struct StringViewComparator {
  using is_transparent = std::true_type;
  bool operator()(const std::string& lhs, const std::string& rhs) const {
    return lhs < rhs;
  }
  bool operator()(ExtendedStringView lhs, const std::string& rhs) const {
    return lhs < fxl::StringView(rhs);
  }
  bool operator()(const std::string& lhs, ExtendedStringView rhs) const {
    return fxl::StringView(lhs) < rhs;
  }
};

}  // namespace convert

#endif  // PERIDOT_LIB_CONVERT_CONVERT_H_
