// 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_json_message_codec.h"

#include "rapidjson/reader.h"
#include "rapidjson/writer.h"

#include <gmodule.h>

G_DEFINE_QUARK(fl_json_message_codec_error_quark, fl_json_message_codec_error)

struct _FlJsonMessageCodec {
  FlMessageCodec parent_instance;
};

G_DEFINE_TYPE(FlJsonMessageCodec,
              fl_json_message_codec,
              fl_message_codec_get_type())

// Recursively writes #FlValue objects using rapidjson.
static gboolean write_value(rapidjson::Writer<rapidjson::StringBuffer>& writer,
                            FlValue* value,
                            GError** error) {
  if (value == nullptr) {
    writer.Null();
    return TRUE;
  }

  switch (fl_value_get_type(value)) {
    case FL_VALUE_TYPE_NULL:
      writer.Null();
      break;
    case FL_VALUE_TYPE_BOOL:
      writer.Bool(fl_value_get_bool(value));
      break;
    case FL_VALUE_TYPE_INT:
      writer.Int64(fl_value_get_int(value));
      break;
    case FL_VALUE_TYPE_FLOAT:
      writer.Double(fl_value_get_float(value));
      break;
    case FL_VALUE_TYPE_STRING:
      writer.String(fl_value_get_string(value));
      break;
    case FL_VALUE_TYPE_UINT8_LIST: {
      writer.StartArray();
      const uint8_t* data = fl_value_get_uint8_list(value);
      for (size_t i = 0; i < fl_value_get_length(value); i++)
        writer.Int(data[i]);
      writer.EndArray();
      break;
    }
    case FL_VALUE_TYPE_INT32_LIST: {
      writer.StartArray();
      const int32_t* data = fl_value_get_int32_list(value);
      for (size_t i = 0; i < fl_value_get_length(value); i++)
        writer.Int(data[i]);
      writer.EndArray();
      break;
    }
    case FL_VALUE_TYPE_INT64_LIST: {
      writer.StartArray();
      const int64_t* data = fl_value_get_int64_list(value);
      for (size_t i = 0; i < fl_value_get_length(value); i++)
        writer.Int64(data[i]);
      writer.EndArray();
      break;
    }
    case FL_VALUE_TYPE_FLOAT_LIST: {
      writer.StartArray();
      const double* data = fl_value_get_float_list(value);
      for (size_t i = 0; i < fl_value_get_length(value); i++)
        writer.Double(data[i]);
      writer.EndArray();
      break;
    }
    case FL_VALUE_TYPE_LIST: {
      writer.StartArray();
      for (size_t i = 0; i < fl_value_get_length(value); i++)
        if (!write_value(writer, fl_value_get_list_value(value, i), error))
          return FALSE;
      writer.EndArray();
      break;
    }
    case FL_VALUE_TYPE_MAP: {
      writer.StartObject();
      for (size_t i = 0; i < fl_value_get_length(value); i++) {
        FlValue* key = fl_value_get_map_key(value, i);
        if (fl_value_get_type(key) != FL_VALUE_TYPE_STRING) {
          g_set_error(error, FL_JSON_MESSAGE_CODEC_ERROR,
                      FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE,
                      "Invalid object key type");
          return FALSE;
        }
        writer.Key(fl_value_get_string(key));
        if (!write_value(writer, fl_value_get_map_value(value, i), error))
          return FALSE;
      }
      writer.EndObject();
      break;
    }
    default:
      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;
  }

  return TRUE;
}

// Handler to parse JSON using rapidjson in SAX mode.
struct FlValueHandler {
  GPtrArray* stack;
  FlValue* key;
  GError* error;

  FlValueHandler() {
    stack = g_ptr_array_new_with_free_func(
        reinterpret_cast<GDestroyNotify>(fl_value_unref));
    key = nullptr;
    error = nullptr;
  }

  ~FlValueHandler() {
    g_ptr_array_unref(stack);
    if (key != nullptr)
      fl_value_unref(key);
    if (error != nullptr)
      g_error_free(error);
  }

  // Gets the current head of the stack.
  FlValue* get_head() {
    if (stack->len == 0)
      return nullptr;
    return static_cast<FlValue*>(g_ptr_array_index(stack, stack->len - 1));
  }

  // Pushes a value onto the stack.
  void push(FlValue* value) { g_ptr_array_add(stack, fl_value_ref(value)); }

  // Pops the stack.
  void pop() { g_ptr_array_remove_index(stack, stack->len - 1); }

  // Adds a new value to the stack.
  bool add(FlValue* value) {
    g_autoptr(FlValue) owned_value = value;
    FlValue* head = get_head();
    if (head == nullptr) {
      push(owned_value);
    } else if (fl_value_get_type(head) == FL_VALUE_TYPE_LIST) {
      fl_value_append(head, owned_value);
    } else if (fl_value_get_type(head) == FL_VALUE_TYPE_MAP) {
      fl_value_set_take(head, key, fl_value_ref(owned_value));
      key = nullptr;
    } else {
      g_set_error(&error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
                  "Can't add value to non container");
      return false;
    }

    if (fl_value_get_type(owned_value) == FL_VALUE_TYPE_LIST ||
        fl_value_get_type(owned_value) == FL_VALUE_TYPE_MAP)
      push(value);

    return true;
  }

  // The following implements the rapidjson SAX API.

  bool Null() { return add(fl_value_new_null()); }

  bool Bool(bool b) { return add(fl_value_new_bool(b)); }

  bool Int(int i) { return add(fl_value_new_int(i)); }

  bool Uint(unsigned i) { return add(fl_value_new_int(i)); }

  bool Int64(int64_t i) { return add(fl_value_new_int(i)); }

  bool Uint64(uint64_t i) {
    // For some reason (bug in rapidjson?) this is not returned in Int64.
    if (i == G_MAXINT64)
      return add(fl_value_new_int(i));
    else
      return add(fl_value_new_float(i));
  }

  bool Double(double d) { return add(fl_value_new_float(d)); }

  bool RawNumber(const char* str, rapidjson::SizeType length, bool copy) {
    g_set_error(&error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED,
                "RawNumber not supported");
    return false;
  }

  bool String(const char* str, rapidjson::SizeType length, bool copy) {
    FlValue* v = fl_value_new_string_sized(str, length);
    return add(v);
  }

  bool StartObject() { return add(fl_value_new_map()); }

  bool Key(const char* str, rapidjson::SizeType length, bool copy) {
    if (key != nullptr)
      fl_value_unref(key);
    key = fl_value_new_string_sized(str, length);
    return true;
  }

  bool EndObject(rapidjson::SizeType memberCount) {
    pop();
    return true;
  }

  bool StartArray() { return add(fl_value_new_list()); }

  bool EndArray(rapidjson::SizeType elementCount) {
    pop();
    return true;
  }
};

// Implements FlMessageCodec:encode_message.
static GBytes* fl_json_message_codec_encode_message(FlMessageCodec* codec,
                                                    FlValue* message,
                                                    GError** error) {
  rapidjson::StringBuffer buffer;
  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);

  if (!write_value(writer, message, error))
    return nullptr;

  const gchar* text = buffer.GetString();
  return g_bytes_new(text, strlen(text));
}

// Implements FlMessageCodec:decode_message.
static FlValue* fl_json_message_codec_decode_message(FlMessageCodec* codec,
                                                     GBytes* message,
                                                     GError** error) {
  gsize data_length;
  const gchar* data =
      static_cast<const char*>(g_bytes_get_data(message, &data_length));
  if (!g_utf8_validate(data, data_length, nullptr)) {
    g_set_error(error, FL_JSON_MESSAGE_CODEC_ERROR,
                FL_JSON_MESSAGE_CODEC_ERROR_INVALID_UTF8,
                "Message is not valid UTF8");
    return nullptr;
  }

  FlValueHandler handler;
  rapidjson::Reader reader;
  rapidjson::MemoryStream ss(data, data_length);
  if (!reader.Parse(ss, handler)) {
    if (handler.error != nullptr) {
      g_propagate_error(error, handler.error);
      handler.error = nullptr;
    } else {
      g_set_error(error, FL_JSON_MESSAGE_CODEC_ERROR,
                  FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON,
                  "Message is not valid JSON");
    }
    return nullptr;
  }

  FlValue* value = handler.get_head();
  if (value == nullptr) {
    g_set_error(error, FL_JSON_MESSAGE_CODEC_ERROR,
                FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON,
                "Message is not valid JSON");
    return nullptr;
  }

  return fl_value_ref(value);
}

static void fl_json_message_codec_class_init(FlJsonMessageCodecClass* klass) {
  FL_MESSAGE_CODEC_CLASS(klass)->encode_message =
      fl_json_message_codec_encode_message;
  FL_MESSAGE_CODEC_CLASS(klass)->decode_message =
      fl_json_message_codec_decode_message;
}

static void fl_json_message_codec_init(FlJsonMessageCodec* self) {}

G_MODULE_EXPORT FlJsonMessageCodec* fl_json_message_codec_new() {
  return static_cast<FlJsonMessageCodec*>(
      g_object_new(fl_json_message_codec_get_type(), nullptr));
}

G_MODULE_EXPORT gchar* fl_json_message_codec_encode(FlJsonMessageCodec* codec,
                                                    FlValue* value,
                                                    GError** error) {
  g_return_val_if_fail(FL_IS_JSON_CODEC(codec), nullptr);

  rapidjson::StringBuffer buffer;
  rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);

  if (!write_value(writer, value, error))
    return nullptr;

  return g_strdup(buffer.GetString());
}

G_MODULE_EXPORT FlValue* fl_json_message_codec_decode(FlJsonMessageCodec* codec,
                                                      const gchar* text,
                                                      GError** error) {
  g_return_val_if_fail(FL_IS_JSON_CODEC(codec), nullptr);

  g_autoptr(GBytes) data = g_bytes_new_static(text, strlen(text));
  g_autoptr(FlValue) value = fl_json_message_codec_decode_message(
      FL_MESSAGE_CODEC(codec), data, error);
  if (value == nullptr)
    return nullptr;

  return fl_value_ref(value);
}
