// Copyright 2013 The Flutter 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 FLUTTER_FML_MESSAGE_H_
#define FLUTTER_FML_MESSAGE_H_

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <memory>
#include <type_traits>
#include <utility>

#include "flutter/fml/compiler_specific.h"
#include "flutter/fml/macros.h"

namespace fml {

#define FML_SERIALIZE(message, value) \
  if (!message.Encode(value)) {       \
    return false;                     \
  }

#define FML_SERIALIZE_TRAITS(message, value, traits) \
  if (!message.Encode<traits>(value)) {              \
    return false;                                    \
  }

#define FML_DESERIALIZE(message, value) \
  if (!message.Decode(value)) {         \
    return false;                       \
  }

#define FML_DESERIALIZE_TRAITS(message, value, traits) \
  if (!message.Decode<traits>(value)) {                \
    return false;                                      \
  }

class Message;

class MessageSerializable {
 public:
  virtual ~MessageSerializable() = default;

  virtual bool Serialize(Message& message) const = 0;

  virtual bool Deserialize(Message& message) = 0;

  virtual size_t GetSerializableTag() const;
};

// The traits passed to the encode/decode calls that accept traits should be
// something like the following.
//
// class MessageSerializableTraits {
//  static size_t GetSerializableTag(const T&);
//  static std::unique_ptr<T> CreateForSerializableTag(size_t tag);
// };

template <class T>
struct Serializable : public std::integral_constant<
                          bool,
                          std::is_trivially_copyable<T>::value ||
                              std::is_base_of<MessageSerializable, T>::value> {
};

// Utility class to encode and decode |Serializable| types to and from a buffer.
// Elements have to be read back into the same order they were written.
class Message {
 public:
  Message();

  ~Message();

  const uint8_t* GetBuffer() const;

  size_t GetBufferSize() const;

  size_t GetDataLength() const;

  size_t GetSizeRead() const;

  void ResetRead();

  // Encoders.

  template <typename T,
            typename = std::enable_if_t<std::is_trivially_copyable<T>::value>>
  [[nodiscard]] bool Encode(const T& value) {
    if (auto* buffer = PrepareEncode(sizeof(T))) {
      ::memcpy(buffer, &value, sizeof(T));
      return true;
    }
    return false;
  }

  [[nodiscard]] bool Encode(const MessageSerializable& value) {
    return value.Serialize(*this);
  }

  template <typename Traits,
            typename T,
            typename = std::enable_if_t<
                std::is_base_of<MessageSerializable, T>::value>>
  [[nodiscard]] bool Encode(const std::unique_ptr<T>& value) {
    // Encode if null.
    if (!Encode(static_cast<bool>(value))) {
      return false;
    }

    if (!value) {
      return true;
    }

    // Encode the type.
    if (!Encode(Traits::GetSerializableTag(*value.get()))) {
      return false;
    }

    // Encode the value.
    if (!Encode(*value.get())) {
      return false;
    }

    return true;
  }

  // Decoders.

  template <typename T,
            typename = std::enable_if_t<std::is_trivially_copyable<T>::value>>
  [[nodiscard]] bool Decode(T& value) {
    if (auto* buffer = PrepareDecode(sizeof(T))) {
      ::memcpy(&value, buffer, sizeof(T));
      return true;
    }
    return false;
  }

  [[nodiscard]] bool Decode(MessageSerializable& value) {
    return value.Deserialize(*this);
  }

  template <typename Traits,
            typename T,
            typename = std::enable_if_t<
                std::is_base_of<MessageSerializable, T>::value>>
  [[nodiscard]] bool Decode(std::unique_ptr<T>& value) {
    // Decode if null.
    bool is_null = false;
    if (!Decode(is_null)) {
      return false;
    }

    if (is_null) {
      return true;
    }

    // Decode type.
    size_t tag = 0;
    if (!Decode(tag)) {
      return false;
    }

    std::unique_ptr<T> new_value = Traits::CreateForSerializableTag(tag);
    if (!new_value) {
      return false;
    }

    // Decode value.
    if (!Decode(*new_value.get())) {
      return false;
    }

    std::swap(value, new_value);

    return true;
  }

 private:
  uint8_t* buffer_ = nullptr;
  size_t buffer_length_ = 0;
  size_t data_length_ = 0;
  size_t size_read_ = 0;

  [[nodiscard]] bool Reserve(size_t size);

  [[nodiscard]] bool Resize(size_t size);

  [[nodiscard]] uint8_t* PrepareEncode(size_t size);

  [[nodiscard]] uint8_t* PrepareDecode(size_t size);

  FML_DISALLOW_COPY_AND_ASSIGN(Message);
};

}  // namespace fml

#endif  // FLUTTER_FML_MESSAGE_H_
