// Copyright 2022 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_DEVELOPER_DEBUG_SHARED_SERIALIZATION_H_
#define SRC_DEVELOPER_DEBUG_SHARED_SERIALIZATION_H_

#include <optional>
#include <string>
#include <type_traits>
#include <vector>

// This is a simple "serialization" solution for the debug_ipc.
//
// It utilizes template and function overloading to avoid writing serialization and deserialization
// functions twice.
//
// To add serialization support for a type, either
//
//   - For classes owned by us, provide a function `void Serialize(Serializer& ser, uint32_t ver)`
//     in the class.
//   - For classes not owned by us / non-class types, provide a function
//     `Serializer& Serializer::operator|(Type& object)`.
//
// These functions will be used by both serialization and deserialization, although the names only
// contain "serialize". In another word, these functions could also write to the object.

namespace debug {

// To implement a Serializer/Deserializer, inherit this interface.
class Serializer {
 public:
  template <typename T>
  Serializer& operator|(T& val)
    requires std::is_void_v<decltype(val.Serialize(*this, 0))>
  {
    val.Serialize(*this, GetVersion());
    return *this;
  }

  template <typename Integer>
  Serializer& operator|(Integer& val)
    requires std::is_integral_v<Integer>
  {
    SerializeBytes(&val, sizeof(val));
    return *this;
  }

  template <typename Enum>
  Serializer& operator|(Enum& val)
    requires std::is_enum_v<Enum>
  {
    uint32_t v = static_cast<uint32_t>(val);
    *this | v;
    val = static_cast<Enum>(v);
    return *this;
  }

  template <typename T>
  Serializer& operator|(std::optional<T>& val) {
    uint32_t has_value = val.has_value();
    *this | has_value;
    if (has_value) {
      if (!val.has_value()) {
        val.emplace();
      }
      *this | val.value();
    } else if (val.has_value()) {
      val.reset();
    }
    return *this;
  }

  template <typename T>
  Serializer& operator|(std::vector<T>& val) {
    uint32_t size = static_cast<uint32_t>(val.size());
    *this | size;
    val.resize(size);
    for (uint32_t i = 0; i < size; i++) {
      *this | val[i];
    }
    return *this;
  }

  Serializer& operator|(std::string& val);

  // Returns the desired version for serialization.
  virtual uint32_t GetVersion() const = 0;

  // Reads or writes bytes.
  virtual void SerializeBytes(void* data, uint32_t size) = 0;

  virtual ~Serializer();
};

}  // namespace debug

namespace debug_ipc {

using Serializer = debug::Serializer;  // for convenience.

}  // namespace debug_ipc

#endif  // SRC_DEVELOPER_DEBUG_SHARED_SERIALIZATION_H_
