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

#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h"
#include "flutter/shell/platform/linux/fl_standard_message_codec_private.h"

#include <gmodule.h>

#include <cstring>

// See lib/src/services/message_codecs.dart in Flutter source for description of
// encoding.

// Type values.
static constexpr int kValueNull = 0;
static constexpr int kValueTrue = 1;
static constexpr int kValueFalse = 2;
static constexpr int kValueInt32 = 3;
static constexpr int kValueInt64 = 4;
static constexpr int kValueFloat64 = 6;
static constexpr int kValueString = 7;
static constexpr int kValueUint8List = 8;
static constexpr int kValueInt32List = 9;
static constexpr int kValueInt64List = 10;
static constexpr int kValueFloat64List = 11;
static constexpr int kValueList = 12;
static constexpr int kValueMap = 13;

struct _FlStandardMessageCodec {
  FlMessageCodec parent_instance;
};

G_DEFINE_TYPE(FlStandardMessageCodec,
              fl_standard_message_codec,
              fl_message_codec_get_type())

// Functions to write standard C number types.

static void write_uint8(GByteArray* buffer, uint8_t value) {
  g_byte_array_append(buffer, &value, sizeof(uint8_t));
}

static void write_uint16(GByteArray* buffer, uint16_t value) {
  g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
                      sizeof(uint16_t));
}

static void write_uint32(GByteArray* buffer, uint32_t value) {
  g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
                      sizeof(uint32_t));
}

static void write_int32(GByteArray* buffer, int32_t value) {
  g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
                      sizeof(int32_t));
}

static void write_int64(GByteArray* buffer, int64_t value) {
  g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
                      sizeof(int64_t));
}

static void write_float64(GByteArray* buffer, double value) {
  g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
                      sizeof(double));
}

// Write padding bytes to align to @align multiple of bytes.
static void write_align(GByteArray* buffer, guint align) {
  while (buffer->len % align != 0) {
    write_uint8(buffer, 0);
  }
}

// Checks there is enough data in @buffer to be read.
static gboolean check_size(GBytes* buffer,
                           size_t offset,
                           size_t required,
                           GError** error) {
  if (offset + required > g_bytes_get_size(buffer)) {
    g_set_error(error, FL_MESSAGE_CODEC_ERROR,
                FL_MESSAGE_CODEC_ERROR_OUT_OF_DATA, "Unexpected end of data");
    return FALSE;
  }
  return TRUE;
}

// Skip bytes to align next read on @align multiple of bytes.
static gboolean read_align(GBytes* buffer,
                           size_t* offset,
                           size_t align,
                           GError** error) {
  if ((*offset) % align == 0) {
    return TRUE;
  }

  size_t required = align - (*offset) % align;
  if (!check_size(buffer, *offset, required, error)) {
    return FALSE;
  }

  (*offset) += required;
  return TRUE;
}

// Gets a pointer to the given offset in @buffer.
static const uint8_t* get_data(GBytes* buffer, size_t* offset) {
  return static_cast<const uint8_t*>(g_bytes_get_data(buffer, nullptr)) +
         *offset;
}

// Reads an unsigned 8 bit number from @buffer and writes it to @value.
// Returns TRUE if successful, otherwise sets an error.
static gboolean read_uint8(GBytes* buffer,
                           size_t* offset,
                           uint8_t* value,
                           GError** error) {
  if (!check_size(buffer, *offset, sizeof(uint8_t), error)) {
    return FALSE;
  }

  *value = get_data(buffer, offset)[0];
  (*offset)++;
  return TRUE;
}

// Reads an unsigned 16 bit integer from @buffer and writes it to @value.
// Returns TRUE if successful, otherwise sets an error.
static gboolean read_uint16(GBytes* buffer,
                            size_t* offset,
                            uint16_t* value,
                            GError** error) {
  if (!check_size(buffer, *offset, sizeof(uint16_t), error)) {
    return FALSE;
  }

  *value = reinterpret_cast<const uint16_t*>(get_data(buffer, offset))[0];
  *offset += sizeof(uint16_t);
  return TRUE;
}

// Reads an unsigned 32 bit integer from @buffer and writes it to @value.
// Returns TRUE if successful, otherwise sets an error.
static gboolean read_uint32(GBytes* buffer,
                            size_t* offset,
                            uint32_t* value,
                            GError** error) {
  if (!check_size(buffer, *offset, sizeof(uint32_t), error)) {
    return FALSE;
  }

  *value = reinterpret_cast<const uint32_t*>(get_data(buffer, offset))[0];
  *offset += sizeof(uint32_t);
  return TRUE;
}

// Reads a #FL_VALUE_TYPE_INT stored as a signed 32 bit integer from @buffer.
// Returns a new #FlValue of type #FL_VALUE_TYPE_INT if successful or %NULL on
// error.
static FlValue* read_int32_value(GBytes* buffer,
                                 size_t* offset,
                                 GError** error) {
  if (!check_size(buffer, *offset, sizeof(int32_t), error)) {
    return nullptr;
  }

  FlValue* value = fl_value_new_int(
      reinterpret_cast<const int32_t*>(get_data(buffer, offset))[0]);
  *offset += sizeof(int32_t);
  return value;
}

// Reads a #FL_VALUE_TYPE_INT stored as a signed 64 bit integer from @buffer.
// Returns a new #FlValue of type #FL_VALUE_TYPE_INT if successful or %NULL on
// error.
static FlValue* read_int64_value(GBytes* buffer,
                                 size_t* offset,
                                 GError** error) {
  if (!check_size(buffer, *offset, sizeof(int64_t), error)) {
    return nullptr;
  }

  FlValue* value = fl_value_new_int(
      reinterpret_cast<const int64_t*>(get_data(buffer, offset))[0]);
  *offset += sizeof(int64_t);
  return value;
}

// Reads a 64 bit floating point number from @buffer and writes it to @value.
// Returns a new #FlValue of type #FL_VALUE_TYPE_FLOAT if successful or %NULL on
// error.
static FlValue* read_float64_value(GBytes* buffer,
                                   size_t* offset,
                                   GError** error) {
  if (!read_align(buffer, offset, 8, error)) {
    return nullptr;
  }
  if (!check_size(buffer, *offset, sizeof(double), error)) {
    return nullptr;
  }

  FlValue* value = fl_value_new_float(
      reinterpret_cast<const double*>(get_data(buffer, offset))[0]);
  *offset += sizeof(double);
  return value;
}

// Reads an UTF-8 text string from @buffer in standard codec format.
// Returns a new #FlValue of type #FL_VALUE_TYPE_STRING if successful or %NULL
// on error.
static FlValue* read_string_value(FlStandardMessageCodec* self,
                                  GBytes* buffer,
                                  size_t* offset,
                                  GError** error) {
  uint32_t length;
  if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
                                           error)) {
    return nullptr;
  }
  if (!check_size(buffer, *offset, length, error)) {
    return nullptr;
  }
  FlValue* value = fl_value_new_string_sized(
      reinterpret_cast<const gchar*>(get_data(buffer, offset)), length);
  *offset += length;
  return value;
}

// Reads an unsigned 8 bit list from @buffer in standard codec format.
// Returns a new #FlValue of type #FL_VALUE_TYPE_UINT8_LIST if successful or
// %NULL on error.
static FlValue* read_uint8_list_value(FlStandardMessageCodec* self,
                                      GBytes* buffer,
                                      size_t* offset,
                                      GError** error) {
  uint32_t length;
  if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
                                           error)) {
    return nullptr;
  }
  if (!check_size(buffer, *offset, sizeof(uint8_t) * length, error)) {
    return nullptr;
  }
  FlValue* value = fl_value_new_uint8_list(get_data(buffer, offset), length);
  *offset += length;
  return value;
}

// Reads a signed 32 bit list from @buffer in standard codec format.
// Returns a new #FlValue of type #FL_VALUE_TYPE_INT32_LIST if successful or
// %NULL on error.
static FlValue* read_int32_list_value(FlStandardMessageCodec* self,
                                      GBytes* buffer,
                                      size_t* offset,
                                      GError** error) {
  uint32_t length;
  if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
                                           error)) {
    return nullptr;
  }
  if (!read_align(buffer, offset, 4, error)) {
    return nullptr;
  }
  if (!check_size(buffer, *offset, sizeof(int32_t) * length, error)) {
    return nullptr;
  }
  FlValue* value = fl_value_new_int32_list(
      reinterpret_cast<const int32_t*>(get_data(buffer, offset)), length);
  *offset += sizeof(int32_t) * length;
  return value;
}

// Reads a signed 64 bit list from @buffer in standard codec format.
// Returns a new #FlValue of type #FL_VALUE_TYPE_INT64_LIST if successful or
// %NULL on error.
static FlValue* read_int64_list_value(FlStandardMessageCodec* self,
                                      GBytes* buffer,
                                      size_t* offset,
                                      GError** error) {
  uint32_t length;
  if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
                                           error)) {
    return nullptr;
  }
  if (!read_align(buffer, offset, 8, error)) {
    return nullptr;
  }
  if (!check_size(buffer, *offset, sizeof(int64_t) * length, error)) {
    return nullptr;
  }
  FlValue* value = fl_value_new_int64_list(
      reinterpret_cast<const int64_t*>(get_data(buffer, offset)), length);
  *offset += sizeof(int64_t) * length;
  return value;
}

// Reads a floating point number list from @buffer in standard codec format.
// Returns a new #FlValue of type #FL_VALUE_TYPE_FLOAT_LIST if successful or
// %NULL on error.
static FlValue* read_float64_list_value(FlStandardMessageCodec* self,
                                        GBytes* buffer,
                                        size_t* offset,
                                        GError** error) {
  uint32_t length;
  if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
                                           error)) {
    return nullptr;
  }
  if (!read_align(buffer, offset, 8, error)) {
    return nullptr;
  }
  if (!check_size(buffer, *offset, sizeof(double) * length, error)) {
    return nullptr;
  }
  FlValue* value = fl_value_new_float_list(
      reinterpret_cast<const double*>(get_data(buffer, offset)), length);
  *offset += sizeof(double) * length;
  return value;
}

// Reads a list from @buffer in standard codec format.
// Returns a new #FlValue of type #FL_VALUE_TYPE_LIST if successful or %NULL on
// error.
static FlValue* read_list_value(FlStandardMessageCodec* self,
                                GBytes* buffer,
                                size_t* offset,
                                GError** error) {
  uint32_t length;
  if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
                                           error)) {
    return nullptr;
  }

  g_autoptr(FlValue) list = fl_value_new_list();
  for (size_t i = 0; i < length; i++) {
    g_autoptr(FlValue) child =
        fl_standard_message_codec_read_value(self, buffer, offset, error);
    if (child == nullptr) {
      return nullptr;
    }
    fl_value_append(list, child);
  }

  return fl_value_ref(list);
}

// Reads a map from @buffer in standard codec format.
// Returns a new #FlValue of type #FL_VALUE_TYPE_MAP if successful or %NULL on
// error.
static FlValue* read_map_value(FlStandardMessageCodec* self,
                               GBytes* buffer,
                               size_t* offset,
                               GError** error) {
  uint32_t length;
  if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
                                           error)) {
    return nullptr;
  }

  g_autoptr(FlValue) map = fl_value_new_map();
  for (size_t i = 0; i < length; i++) {
    g_autoptr(FlValue) key =
        fl_standard_message_codec_read_value(self, buffer, offset, error);
    if (key == nullptr) {
      return nullptr;
    }
    g_autoptr(FlValue) value =
        fl_standard_message_codec_read_value(self, buffer, offset, error);
    if (value == nullptr) {
      return nullptr;
    }
    fl_value_set(map, key, value);
  }

  return fl_value_ref(map);
}

// Implements FlMessageCodec::encode_message.
static GBytes* fl_standard_message_codec_encode_message(FlMessageCodec* codec,
                                                        FlValue* message,
                                                        GError** error) {
  FlStandardMessageCodec* self =
      reinterpret_cast<FlStandardMessageCodec*>(codec);

  g_autoptr(GByteArray) buffer = g_byte_array_new();
  if (!fl_standard_message_codec_write_value(self, buffer, message, error)) {
    return nullptr;
  }
  return g_byte_array_free_to_bytes(
      static_cast<GByteArray*>(g_steal_pointer(&buffer)));
}

// Implements FlMessageCodec::decode_message.
static FlValue* fl_standard_message_codec_decode_message(FlMessageCodec* codec,
                                                         GBytes* message,
                                                         GError** error) {
  FlStandardMessageCodec* self =
      reinterpret_cast<FlStandardMessageCodec*>(codec);

  size_t offset = 0;
  g_autoptr(FlValue) value =
      fl_standard_message_codec_read_value(self, message, &offset, error);
  if (value == nullptr) {
    return nullptr;
  }

  if (offset != g_bytes_get_size(message)) {
    g_set_error(error, FL_MESSAGE_CODEC_ERROR,
                FL_MESSAGE_CODEC_ERROR_ADDITIONAL_DATA,
                "Unused %zi bytes after standard message",
                g_bytes_get_size(message) - offset);
    return nullptr;
  }

  return fl_value_ref(value);
}

static void fl_standard_message_codec_class_init(
    FlStandardMessageCodecClass* klass) {
  FL_MESSAGE_CODEC_CLASS(klass)->encode_message =
      fl_standard_message_codec_encode_message;
  FL_MESSAGE_CODEC_CLASS(klass)->decode_message =
      fl_standard_message_codec_decode_message;
}

static void fl_standard_message_codec_init(FlStandardMessageCodec* self) {}

G_MODULE_EXPORT FlStandardMessageCodec* fl_standard_message_codec_new() {
  return static_cast<FlStandardMessageCodec*>(
      g_object_new(fl_standard_message_codec_get_type(), nullptr));
}

void fl_standard_message_codec_write_size(FlStandardMessageCodec* codec,
                                          GByteArray* buffer,
                                          uint32_t size) {
  if (size < 254) {
    write_uint8(buffer, size);
  } else if (size <= 0xffff) {
    write_uint8(buffer, 254);
    write_uint16(buffer, size);
  } else {
    write_uint8(buffer, 255);
    write_uint32(buffer, size);
  }
}

gboolean fl_standard_message_codec_read_size(FlStandardMessageCodec* codec,
                                             GBytes* buffer,
                                             size_t* offset,
                                             uint32_t* value,
                                             GError** error) {
  uint8_t value8;
  if (!read_uint8(buffer, offset, &value8, error)) {
    return FALSE;
  }

  if (value8 == 255) {
    if (!read_uint32(buffer, offset, value, error)) {
      return FALSE;
    }
  } else if (value8 == 254) {
    uint16_t value16;
    if (!read_uint16(buffer, offset, &value16, error)) {
      return FALSE;
    }
    *value = value16;
  } else {
    *value = value8;
  }

  return TRUE;
}

gboolean fl_standard_message_codec_write_value(FlStandardMessageCodec* self,
                                               GByteArray* buffer,
                                               FlValue* value,
                                               GError** error) {
  if (value == nullptr) {
    write_uint8(buffer, kValueNull);
    return TRUE;
  }

  switch (fl_value_get_type(value)) {
    case FL_VALUE_TYPE_NULL:
      write_uint8(buffer, kValueNull);
      return TRUE;
    case FL_VALUE_TYPE_BOOL:
      if (fl_value_get_bool(value)) {
        write_uint8(buffer, kValueTrue);
      } else {
        write_uint8(buffer, kValueFalse);
      }
      return TRUE;
    case FL_VALUE_TYPE_INT: {
      int64_t v = fl_value_get_int(value);
      if (v >= INT32_MIN && v <= INT32_MAX) {
        write_uint8(buffer, kValueInt32);
        write_int32(buffer, v);
      } else {
        write_uint8(buffer, kValueInt64);
        write_int64(buffer, v);
      }
      return TRUE;
    }
    case FL_VALUE_TYPE_FLOAT:
      write_uint8(buffer, kValueFloat64);
      write_align(buffer, 8);
      write_float64(buffer, fl_value_get_float(value));
      return TRUE;
    case FL_VALUE_TYPE_STRING: {
      write_uint8(buffer, kValueString);
      const char* text = fl_value_get_string(value);
      size_t length = strlen(text);
      fl_standard_message_codec_write_size(self, buffer, length);
      g_byte_array_append(buffer, reinterpret_cast<const uint8_t*>(text),
                          length);
      return TRUE;
    }
    case FL_VALUE_TYPE_UINT8_LIST: {
      write_uint8(buffer, kValueUint8List);
      size_t length = fl_value_get_length(value);
      fl_standard_message_codec_write_size(self, buffer, length);
      g_byte_array_append(buffer, fl_value_get_uint8_list(value),
                          sizeof(uint8_t) * length);
      return TRUE;
    }
    case FL_VALUE_TYPE_INT32_LIST: {
      write_uint8(buffer, kValueInt32List);
      size_t length = fl_value_get_length(value);
      fl_standard_message_codec_write_size(self, buffer, length);
      write_align(buffer, 4);
      g_byte_array_append(
          buffer,
          reinterpret_cast<const uint8_t*>(fl_value_get_int32_list(value)),
          sizeof(int32_t) * length);
      return TRUE;
    }
    case FL_VALUE_TYPE_INT64_LIST: {
      write_uint8(buffer, kValueInt64List);
      size_t length = fl_value_get_length(value);
      fl_standard_message_codec_write_size(self, buffer, length);
      write_align(buffer, 8);
      g_byte_array_append(
          buffer,
          reinterpret_cast<const uint8_t*>(fl_value_get_int64_list(value)),
          sizeof(int64_t) * length);
      return TRUE;
    }
    case FL_VALUE_TYPE_FLOAT_LIST: {
      write_uint8(buffer, kValueFloat64List);
      size_t length = fl_value_get_length(value);
      fl_standard_message_codec_write_size(self, buffer, length);
      write_align(buffer, 8);
      g_byte_array_append(
          buffer,
          reinterpret_cast<const uint8_t*>(fl_value_get_float_list(value)),
          sizeof(double) * length);
      return TRUE;
    }
    case FL_VALUE_TYPE_LIST:
      write_uint8(buffer, kValueList);
      fl_standard_message_codec_write_size(self, buffer,
                                           fl_value_get_length(value));
      for (size_t i = 0; i < fl_value_get_length(value); i++) {
        if (!fl_standard_message_codec_write_value(
                self, buffer, fl_value_get_list_value(value, i), error)) {
          return FALSE;
        }
      }
      return TRUE;
    case FL_VALUE_TYPE_MAP:
      write_uint8(buffer, kValueMap);
      fl_standard_message_codec_write_size(self, buffer,
                                           fl_value_get_length(value));
      for (size_t i = 0; i < fl_value_get_length(value); i++) {
        if (!fl_standard_message_codec_write_value(
                self, buffer, fl_value_get_map_key(value, i), error) ||
            !fl_standard_message_codec_write_value(
                self, buffer, fl_value_get_map_value(value, i), error)) {
          return FALSE;
        }
      }
      return TRUE;
  }

  g_set_error(error, FL_MESSAGE_CODEC_ERROR,
              FL_MESSAGE_CODEC_ERROR_UNSUPPORTED_TYPE,
              "Unexpected FlValue type %d", fl_value_get_type(value));
  return FALSE;
}

FlValue* fl_standard_message_codec_read_value(FlStandardMessageCodec* self,
                                              GBytes* buffer,
                                              size_t* offset,
                                              GError** error) {
  uint8_t type;
  if (!read_uint8(buffer, offset, &type, error)) {
    return nullptr;
  }

  g_autoptr(FlValue) value = nullptr;
  if (type == kValueNull) {
    return fl_value_new_null();
  } else if (type == kValueTrue) {
    return fl_value_new_bool(TRUE);
  } else if (type == kValueFalse) {
    return fl_value_new_bool(FALSE);
  } else if (type == kValueInt32) {
    value = read_int32_value(buffer, offset, error);
  } else if (type == kValueInt64) {
    value = read_int64_value(buffer, offset, error);
  } else if (type == kValueFloat64) {
    value = read_float64_value(buffer, offset, error);
  } else if (type == kValueString) {
    value = read_string_value(self, buffer, offset, error);
  } else if (type == kValueUint8List) {
    value = read_uint8_list_value(self, buffer, offset, error);
  } else if (type == kValueInt32List) {
    value = read_int32_list_value(self, buffer, offset, error);
  } else if (type == kValueInt64List) {
    value = read_int64_list_value(self, buffer, offset, error);
  } else if (type == kValueFloat64List) {
    value = read_float64_list_value(self, buffer, offset, error);
  } else if (type == kValueList) {
    value = read_list_value(self, buffer, offset, error);
  } else if (type == kValueMap) {
    value = read_map_value(self, buffer, offset, error);
  } else {
    g_set_error(error, FL_MESSAGE_CODEC_ERROR,
                FL_MESSAGE_CODEC_ERROR_UNSUPPORTED_TYPE,
                "Unexpected standard codec type %02x", type);
    return nullptr;
  }

  return value == nullptr ? nullptr : fl_value_ref(value);
}
