// 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);
}
