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

#include <gmodule.h>

struct _FlValue {
  FlValueType type;
  int ref_count;
};

typedef struct {
  FlValue parent;
  bool value;
} FlValueBool;

typedef struct {
  FlValue parent;
  int64_t value;
} FlValueInt;

typedef struct {
  FlValue parent;
  double value;
} FlValueDouble;

typedef struct {
  FlValue parent;
  gchar* value;
} FlValueString;

typedef struct {
  FlValue parent;
  uint8_t* values;
  size_t values_length;
} FlValueUint8List;

typedef struct {
  FlValue parent;
  int32_t* values;
  size_t values_length;
} FlValueInt32List;

typedef struct {
  FlValue parent;
  int64_t* values;
  size_t values_length;
} FlValueInt64List;

typedef struct {
  FlValue parent;
  double* values;
  size_t values_length;
} FlValueFloatList;

typedef struct {
  FlValue parent;
  GPtrArray* values;
} FlValueList;

typedef struct {
  FlValue parent;
  GPtrArray* keys;
  GPtrArray* values;
} FlValueMap;

static FlValue* fl_value_new(FlValueType type, size_t size) {
  FlValue* self = static_cast<FlValue*>(g_malloc0(size));
  self->type = type;
  self->ref_count = 1;
  return self;
}

// Helper function to match GDestroyNotify type.
static void fl_value_destroy(gpointer value) {
  fl_value_unref(static_cast<FlValue*>(value));
}

// Finds the index of a key in a FlValueMap.
// FIXME(robert-ancell) This is highly inefficient, and should be optimised if
// necessary.
static ssize_t fl_value_lookup_index(FlValue* self, FlValue* key) {
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, -1);

  for (size_t i = 0; i < fl_value_get_length(self); i++) {
    FlValue* k = fl_value_get_map_key(self, i);
    if (fl_value_equal(k, key))
      return i;
  }
  return -1;
}

// Converts an integer to a string and adds it to the buffer
static void int_to_string(int64_t value, GString* buffer) {
  g_string_append_printf(buffer, "%" G_GINT64_FORMAT, value);
}

// Converts a floating point number to a string and adds it to the buffer
static void float_to_string(double value, GString* buffer) {
  g_string_append_printf(buffer, "%.16f", value);

  // Strip trailing zeros
  int zero_count = 0;
  for (int i = buffer->len - 1; i >= 0; i--) {
    // Leave one zero after a decimal point
    if (buffer->str[i] == '.') {
      zero_count = zero_count == 0 ? 0 : zero_count - 1;
      break;
    }
    if (buffer->str[i] != '0')
      break;
    zero_count++;
  }
  g_string_truncate(buffer, buffer->len - zero_count);
}

static void value_to_string(FlValue* value, GString* buffer) {
  switch (value->type) {
    case FL_VALUE_TYPE_NULL:
      g_string_append(buffer, "null");
      return;
    case FL_VALUE_TYPE_BOOL:
      if (fl_value_get_bool(value))
        g_string_append(buffer, "true");
      else
        g_string_append(buffer, "false");
      return;
    case FL_VALUE_TYPE_INT:
      int_to_string(fl_value_get_int(value), buffer);
      return;
    case FL_VALUE_TYPE_FLOAT:
      float_to_string(fl_value_get_float(value), buffer);
      return;
    case FL_VALUE_TYPE_STRING: {
      g_string_append(buffer, fl_value_get_string(value));
      return;
    }
    case FL_VALUE_TYPE_UINT8_LIST: {
      g_string_append(buffer, "[");
      const uint8_t* values = fl_value_get_uint8_list(value);
      for (size_t i = 0; i < fl_value_get_length(value); i++) {
        if (i != 0)
          g_string_append(buffer, ", ");
        int_to_string(values[i], buffer);
      }
      g_string_append(buffer, "]");
      return;
    }
    case FL_VALUE_TYPE_INT32_LIST: {
      g_string_append(buffer, "[");
      const int32_t* values = fl_value_get_int32_list(value);
      for (size_t i = 0; i < fl_value_get_length(value); i++) {
        if (i != 0)
          g_string_append(buffer, ", ");
        int_to_string(values[i], buffer);
      }
      g_string_append(buffer, "]");
      return;
    }
    case FL_VALUE_TYPE_INT64_LIST: {
      g_string_append(buffer, "[");
      const int64_t* values = fl_value_get_int64_list(value);
      for (size_t i = 0; i < fl_value_get_length(value); i++) {
        if (i != 0)
          g_string_append(buffer, ", ");
        int_to_string(values[i], buffer);
      }
      g_string_append(buffer, "]");
      return;
    }
    case FL_VALUE_TYPE_FLOAT_LIST: {
      g_string_append(buffer, "[");
      const double* values = fl_value_get_float_list(value);
      for (size_t i = 0; i < fl_value_get_length(value); i++) {
        if (i != 0)
          g_string_append(buffer, ", ");
        float_to_string(values[i], buffer);
      }
      g_string_append(buffer, "]");
      return;
    }
    case FL_VALUE_TYPE_LIST: {
      g_string_append(buffer, "[");
      for (size_t i = 0; i < fl_value_get_length(value); i++) {
        if (i != 0)
          g_string_append(buffer, ", ");
        value_to_string(fl_value_get_list_value(value, i), buffer);
      }
      g_string_append(buffer, "]");
      return;
    }
    case FL_VALUE_TYPE_MAP: {
      g_string_append(buffer, "{");
      for (size_t i = 0; i < fl_value_get_length(value); i++) {
        if (i != 0)
          g_string_append(buffer, ", ");
        value_to_string(fl_value_get_map_key(value, i), buffer);
        g_string_append(buffer, ": ");
        value_to_string(fl_value_get_map_value(value, i), buffer);
      }
      g_string_append(buffer, "}");
      return;
    }
    default:
      g_string_append_printf(buffer, "<unknown type %d>", value->type);
  }
}

G_MODULE_EXPORT FlValue* fl_value_new_null() {
  return fl_value_new(FL_VALUE_TYPE_NULL, sizeof(FlValue));
}

G_MODULE_EXPORT FlValue* fl_value_new_bool(bool value) {
  FlValueBool* self = reinterpret_cast<FlValueBool*>(
      fl_value_new(FL_VALUE_TYPE_BOOL, sizeof(FlValueBool)));
  self->value = value ? true : false;
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_int(int64_t value) {
  FlValueInt* self = reinterpret_cast<FlValueInt*>(
      fl_value_new(FL_VALUE_TYPE_INT, sizeof(FlValueInt)));
  self->value = value;
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_float(double value) {
  FlValueDouble* self = reinterpret_cast<FlValueDouble*>(
      fl_value_new(FL_VALUE_TYPE_FLOAT, sizeof(FlValueDouble)));
  self->value = value;
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_string(const gchar* value) {
  FlValueString* self = reinterpret_cast<FlValueString*>(
      fl_value_new(FL_VALUE_TYPE_STRING, sizeof(FlValueString)));
  self->value = g_strdup(value);
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_string_sized(const gchar* value,
                                                   size_t value_length) {
  FlValueString* self = reinterpret_cast<FlValueString*>(
      fl_value_new(FL_VALUE_TYPE_STRING, sizeof(FlValueString)));
  self->value =
      value_length == 0 ? g_strdup("") : g_strndup(value, value_length);
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_uint8_list(const uint8_t* data,
                                                 size_t data_length) {
  FlValueUint8List* self = reinterpret_cast<FlValueUint8List*>(
      fl_value_new(FL_VALUE_TYPE_UINT8_LIST, sizeof(FlValueUint8List)));
  self->values_length = data_length;
  self->values = static_cast<uint8_t*>(g_malloc(sizeof(uint8_t) * data_length));
  memcpy(self->values, data, sizeof(uint8_t) * data_length);
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_uint8_list_from_bytes(GBytes* data) {
  gsize length;
  const uint8_t* d =
      static_cast<const uint8_t*>(g_bytes_get_data(data, &length));
  return fl_value_new_uint8_list(d, length);
}

G_MODULE_EXPORT FlValue* fl_value_new_int32_list(const int32_t* data,
                                                 size_t data_length) {
  FlValueInt32List* self = reinterpret_cast<FlValueInt32List*>(
      fl_value_new(FL_VALUE_TYPE_INT32_LIST, sizeof(FlValueInt32List)));
  self->values_length = data_length;
  self->values = static_cast<int32_t*>(g_malloc(sizeof(int32_t) * data_length));
  memcpy(self->values, data, sizeof(int32_t) * data_length);
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_int64_list(const int64_t* data,
                                                 size_t data_length) {
  FlValueInt64List* self = reinterpret_cast<FlValueInt64List*>(
      fl_value_new(FL_VALUE_TYPE_INT64_LIST, sizeof(FlValueInt64List)));
  self->values_length = data_length;
  self->values = static_cast<int64_t*>(g_malloc(sizeof(int64_t) * data_length));
  memcpy(self->values, data, sizeof(int64_t) * data_length);
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_float_list(const double* data,
                                                 size_t data_length) {
  FlValueFloatList* self = reinterpret_cast<FlValueFloatList*>(
      fl_value_new(FL_VALUE_TYPE_FLOAT_LIST, sizeof(FlValueFloatList)));
  self->values_length = data_length;
  self->values = static_cast<double*>(g_malloc(sizeof(double) * data_length));
  memcpy(self->values, data, sizeof(double) * data_length);
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_list() {
  FlValueList* self = reinterpret_cast<FlValueList*>(
      fl_value_new(FL_VALUE_TYPE_LIST, sizeof(FlValueList)));
  self->values = g_ptr_array_new_with_free_func(fl_value_destroy);
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_new_list_from_strv(
    const gchar* const* str_array) {
  g_return_val_if_fail(str_array != nullptr, nullptr);
  g_autoptr(FlValue) value = fl_value_new_list();
  for (int i = 0; str_array[i] != nullptr; i++)
    fl_value_append_take(value, fl_value_new_string(str_array[i]));
  return fl_value_ref(value);
}

G_MODULE_EXPORT FlValue* fl_value_new_map() {
  FlValueMap* self = reinterpret_cast<FlValueMap*>(
      fl_value_new(FL_VALUE_TYPE_MAP, sizeof(FlValueMap)));
  self->keys = g_ptr_array_new_with_free_func(fl_value_destroy);
  self->values = g_ptr_array_new_with_free_func(fl_value_destroy);
  return reinterpret_cast<FlValue*>(self);
}

G_MODULE_EXPORT FlValue* fl_value_ref(FlValue* self) {
  g_return_val_if_fail(self != nullptr, nullptr);
  self->ref_count++;
  return self;
}

G_MODULE_EXPORT void fl_value_unref(FlValue* self) {
  g_return_if_fail(self != nullptr);
  g_return_if_fail(self->ref_count > 0);
  self->ref_count--;
  if (self->ref_count != 0)
    return;

  switch (self->type) {
    case FL_VALUE_TYPE_STRING: {
      FlValueString* v = reinterpret_cast<FlValueString*>(self);
      g_free(v->value);
      break;
    }
    case FL_VALUE_TYPE_UINT8_LIST: {
      FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
      g_free(v->values);
      break;
    }
    case FL_VALUE_TYPE_INT32_LIST: {
      FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
      g_free(v->values);
      break;
    }
    case FL_VALUE_TYPE_INT64_LIST: {
      FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
      g_free(v->values);
      break;
    }
    case FL_VALUE_TYPE_FLOAT_LIST: {
      FlValueFloatList* v = reinterpret_cast<FlValueFloatList*>(self);
      g_free(v->values);
      break;
    }
    case FL_VALUE_TYPE_LIST: {
      FlValueList* v = reinterpret_cast<FlValueList*>(self);
      g_ptr_array_unref(v->values);
      break;
    }
    case FL_VALUE_TYPE_MAP: {
      FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
      g_ptr_array_unref(v->keys);
      g_ptr_array_unref(v->values);
      break;
    }
    case FL_VALUE_TYPE_NULL:
    case FL_VALUE_TYPE_BOOL:
    case FL_VALUE_TYPE_INT:
    case FL_VALUE_TYPE_FLOAT:
      break;
  }
  g_free(self);
}

G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue* self) {
  g_return_val_if_fail(self != nullptr, FL_VALUE_TYPE_NULL);
  return self->type;
}

G_MODULE_EXPORT bool fl_value_equal(FlValue* a, FlValue* b) {
  g_return_val_if_fail(a != nullptr, false);
  g_return_val_if_fail(b != nullptr, false);

  if (a->type != b->type)
    return false;

  switch (a->type) {
    case FL_VALUE_TYPE_NULL:
      return true;
    case FL_VALUE_TYPE_BOOL:
      return fl_value_get_bool(a) == fl_value_get_bool(b);
    case FL_VALUE_TYPE_INT:
      return fl_value_get_int(a) == fl_value_get_int(b);
    case FL_VALUE_TYPE_FLOAT:
      return fl_value_get_float(a) == fl_value_get_float(b);
    case FL_VALUE_TYPE_STRING: {
      FlValueString* a_ = reinterpret_cast<FlValueString*>(a);
      FlValueString* b_ = reinterpret_cast<FlValueString*>(b);
      return g_strcmp0(a_->value, b_->value) == 0;
    }
    case FL_VALUE_TYPE_UINT8_LIST: {
      if (fl_value_get_length(a) != fl_value_get_length(b))
        return false;
      const uint8_t* values_a = fl_value_get_uint8_list(a);
      const uint8_t* values_b = fl_value_get_uint8_list(b);
      for (size_t i = 0; i < fl_value_get_length(a); i++) {
        if (values_a[i] != values_b[i])
          return false;
      }
      return true;
    }
    case FL_VALUE_TYPE_INT32_LIST: {
      if (fl_value_get_length(a) != fl_value_get_length(b))
        return false;
      const int32_t* values_a = fl_value_get_int32_list(a);
      const int32_t* values_b = fl_value_get_int32_list(b);
      for (size_t i = 0; i < fl_value_get_length(a); i++) {
        if (values_a[i] != values_b[i])
          return false;
      }
      return true;
    }
    case FL_VALUE_TYPE_INT64_LIST: {
      if (fl_value_get_length(a) != fl_value_get_length(b))
        return false;
      const int64_t* values_a = fl_value_get_int64_list(a);
      const int64_t* values_b = fl_value_get_int64_list(b);
      for (size_t i = 0; i < fl_value_get_length(a); i++) {
        if (values_a[i] != values_b[i])
          return false;
      }
      return true;
    }
    case FL_VALUE_TYPE_FLOAT_LIST: {
      if (fl_value_get_length(a) != fl_value_get_length(b))
        return false;
      const double* values_a = fl_value_get_float_list(a);
      const double* values_b = fl_value_get_float_list(b);
      for (size_t i = 0; i < fl_value_get_length(a); i++) {
        if (values_a[i] != values_b[i])
          return false;
      }
      return true;
    }
    case FL_VALUE_TYPE_LIST: {
      if (fl_value_get_length(a) != fl_value_get_length(b))
        return false;
      for (size_t i = 0; i < fl_value_get_length(a); i++) {
        if (!fl_value_equal(fl_value_get_list_value(a, i),
                            fl_value_get_list_value(b, i)))
          return false;
      }
      return true;
    }
    case FL_VALUE_TYPE_MAP: {
      if (fl_value_get_length(a) != fl_value_get_length(b))
        return false;
      for (size_t i = 0; i < fl_value_get_length(a); i++) {
        FlValue* key = fl_value_get_map_key(a, i);
        FlValue* value_b = fl_value_lookup(b, key);
        if (value_b == nullptr)
          return false;
        FlValue* value_a = fl_value_get_map_value(a, i);
        if (!fl_value_equal(value_a, value_b))
          return false;
      }
      return true;
    }
  }
}

G_MODULE_EXPORT void fl_value_append(FlValue* self, FlValue* value) {
  g_return_if_fail(self != nullptr);
  g_return_if_fail(self->type == FL_VALUE_TYPE_LIST);
  g_return_if_fail(value != nullptr);

  fl_value_append_take(self, fl_value_ref(value));
}

G_MODULE_EXPORT void fl_value_append_take(FlValue* self, FlValue* value) {
  g_return_if_fail(self != nullptr);
  g_return_if_fail(self->type == FL_VALUE_TYPE_LIST);
  g_return_if_fail(value != nullptr);

  FlValueList* v = reinterpret_cast<FlValueList*>(self);
  g_ptr_array_add(v->values, value);
}

G_MODULE_EXPORT void fl_value_set(FlValue* self, FlValue* key, FlValue* value) {
  g_return_if_fail(self != nullptr);
  g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
  g_return_if_fail(key != nullptr);
  g_return_if_fail(value != nullptr);

  fl_value_set_take(self, fl_value_ref(key), fl_value_ref(value));
}

G_MODULE_EXPORT void fl_value_set_take(FlValue* self,
                                       FlValue* key,
                                       FlValue* value) {
  g_return_if_fail(self != nullptr);
  g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
  g_return_if_fail(key != nullptr);
  g_return_if_fail(value != nullptr);

  FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
  ssize_t index = fl_value_lookup_index(self, key);
  if (index < 0) {
    g_ptr_array_add(v->keys, key);
    g_ptr_array_add(v->values, value);
  } else {
    fl_value_destroy(v->keys->pdata[index]);
    v->keys->pdata[index] = key;
    fl_value_destroy(v->values->pdata[index]);
    v->values->pdata[index] = value;
  }
}

G_MODULE_EXPORT void fl_value_set_string(FlValue* self,
                                         const gchar* key,
                                         FlValue* value) {
  g_return_if_fail(self != nullptr);
  g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
  g_return_if_fail(key != nullptr);
  g_return_if_fail(value != nullptr);

  fl_value_set_take(self, fl_value_new_string(key), fl_value_ref(value));
}

G_MODULE_EXPORT void fl_value_set_string_take(FlValue* self,
                                              const gchar* key,
                                              FlValue* value) {
  g_return_if_fail(self != nullptr);
  g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
  g_return_if_fail(key != nullptr);
  g_return_if_fail(value != nullptr);

  fl_value_set_take(self, fl_value_new_string(key), value);
}

G_MODULE_EXPORT bool fl_value_get_bool(FlValue* self) {
  g_return_val_if_fail(self != nullptr, FALSE);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_BOOL, FALSE);
  FlValueBool* v = reinterpret_cast<FlValueBool*>(self);
  return v->value;
}

G_MODULE_EXPORT int64_t fl_value_get_int(FlValue* self) {
  g_return_val_if_fail(self != nullptr, 0);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_INT, 0);
  FlValueInt* v = reinterpret_cast<FlValueInt*>(self);
  return v->value;
}

G_MODULE_EXPORT double fl_value_get_float(FlValue* self) {
  g_return_val_if_fail(self != nullptr, 0.0);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_FLOAT, 0.0);
  FlValueDouble* v = reinterpret_cast<FlValueDouble*>(self);
  return v->value;
}

G_MODULE_EXPORT const gchar* fl_value_get_string(FlValue* self) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_STRING, nullptr);
  FlValueString* v = reinterpret_cast<FlValueString*>(self);
  return v->value;
}

G_MODULE_EXPORT const uint8_t* fl_value_get_uint8_list(FlValue* self) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_UINT8_LIST, nullptr);
  FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
  return v->values;
}

G_MODULE_EXPORT const int32_t* fl_value_get_int32_list(FlValue* self) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_INT32_LIST, nullptr);
  FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
  return v->values;
}

G_MODULE_EXPORT const int64_t* fl_value_get_int64_list(FlValue* self) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_INT64_LIST, nullptr);
  FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
  return v->values;
}

G_MODULE_EXPORT const double* fl_value_get_float_list(FlValue* self) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_FLOAT_LIST, nullptr);
  FlValueFloatList* v = reinterpret_cast<FlValueFloatList*>(self);
  return v->values;
}

G_MODULE_EXPORT size_t fl_value_get_length(FlValue* self) {
  g_return_val_if_fail(self != nullptr, 0);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_UINT8_LIST ||
                           self->type == FL_VALUE_TYPE_INT32_LIST ||
                           self->type == FL_VALUE_TYPE_INT64_LIST ||
                           self->type == FL_VALUE_TYPE_FLOAT_LIST ||
                           self->type == FL_VALUE_TYPE_LIST ||
                           self->type == FL_VALUE_TYPE_MAP,
                       0);

  switch (self->type) {
    case FL_VALUE_TYPE_UINT8_LIST: {
      FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
      return v->values_length;
    }
    case FL_VALUE_TYPE_INT32_LIST: {
      FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
      return v->values_length;
    }
    case FL_VALUE_TYPE_INT64_LIST: {
      FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
      return v->values_length;
    }
    case FL_VALUE_TYPE_FLOAT_LIST: {
      FlValueFloatList* v = reinterpret_cast<FlValueFloatList*>(self);
      return v->values_length;
    }
    case FL_VALUE_TYPE_LIST: {
      FlValueList* v = reinterpret_cast<FlValueList*>(self);
      return v->values->len;
    }
    case FL_VALUE_TYPE_MAP: {
      FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
      return v->keys->len;
    }
    case FL_VALUE_TYPE_NULL:
    case FL_VALUE_TYPE_BOOL:
    case FL_VALUE_TYPE_INT:
    case FL_VALUE_TYPE_FLOAT:
    case FL_VALUE_TYPE_STRING:
      return 0;
  }

  return 0;
}

G_MODULE_EXPORT FlValue* fl_value_get_list_value(FlValue* self, size_t index) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_LIST, nullptr);

  FlValueList* v = reinterpret_cast<FlValueList*>(self);
  return static_cast<FlValue*>(g_ptr_array_index(v->values, index));
}

G_MODULE_EXPORT FlValue* fl_value_get_map_key(FlValue* self, size_t index) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, nullptr);

  FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
  return static_cast<FlValue*>(g_ptr_array_index(v->keys, index));
}

G_MODULE_EXPORT FlValue* fl_value_get_map_value(FlValue* self, size_t index) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, nullptr);

  FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
  return static_cast<FlValue*>(g_ptr_array_index(v->values, index));
}

G_MODULE_EXPORT FlValue* fl_value_lookup(FlValue* self, FlValue* key) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, nullptr);

  ssize_t index = fl_value_lookup_index(self, key);
  if (index < 0)
    return nullptr;
  return fl_value_get_map_value(self, index);
}

FlValue* fl_value_lookup_string(FlValue* self, const gchar* key) {
  g_return_val_if_fail(self != nullptr, nullptr);
  g_autoptr(FlValue) string_key = fl_value_new_string(key);
  return fl_value_lookup(self, string_key);
}

gchar* fl_value_to_string(FlValue* value) {
  GString* buffer = g_string_new("");
  value_to_string(value, buffer);
  return g_string_free(buffer, FALSE);
}
