/* prefix-tree.c generated by valac 0.56.19, the Vala compiler
 * generated from prefix-tree.vala, do not modify */

#include "word-completion.h"
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <gee.h>
#include <glib-object.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

enum  {
	SCRATCH_PLUGINS_PREFIX_TREE_0_PROPERTY,
	SCRATCH_PLUGINS_PREFIX_TREE_NUM_PROPERTIES
};
static GParamSpec* scratch_plugins_prefix_tree_properties[SCRATCH_PLUGINS_PREFIX_TREE_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))

struct _ScratchPluginsPrefixTreePrivate {
	ScratchPluginsPrefixNode* root;
};

static gint ScratchPluginsPrefixTree_private_offset;
static gpointer scratch_plugins_prefix_tree_parent_class = NULL;
static GType scratch_plugins_prefix_tree_type_id = 0;

static void scratch_plugins_prefix_tree_insert_at (ScratchPluginsPrefixTree* self,
                                            const gchar* word,
                                            ScratchPluginsPrefixNode* node,
                                            gint i);
static gint __lambda4_ (ScratchPluginsPrefixTree* self,
                 ScratchPluginsPrefixNode* c1,
                 ScratchPluginsPrefixNode* c2);
static gint ___lambda4__gcompare_data_func (gconstpointer a,
                                     gconstpointer b,
                                     gpointer self);
static ScratchPluginsPrefixNode* scratch_plugins_prefix_tree_find_prefix_at (ScratchPluginsPrefixTree* self,
                                                                      const gchar* prefix,
                                                                      ScratchPluginsPrefixNode* node,
                                                                      gint i);
static void scratch_plugins_prefix_tree_get_all_matches_rec (ScratchPluginsPrefixTree* self,
                                                      ScratchPluginsPrefixNode* node,
                                                      GString** sbuilder,
                                                      GList** matches);
static GObject * scratch_plugins_prefix_tree_constructor (GType type,
                                                   guint n_construct_properties,
                                                   GObjectConstructParam * construct_properties);
static void scratch_plugins_prefix_tree_finalize (GObject * obj);

static inline gpointer
scratch_plugins_prefix_tree_get_instance_private (ScratchPluginsPrefixTree* self)
{
	return G_STRUCT_MEMBER_P (self, ScratchPluginsPrefixTree_private_offset);
}

void
scratch_plugins_prefix_tree_clear (ScratchPluginsPrefixTree* self)
{
	ScratchPluginsPrefixNode* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = scratch_plugins_prefix_node_new ();
	_g_object_unref0 (self->priv->root);
	self->priv->root = _tmp0_;
}

void
scratch_plugins_prefix_tree_insert (ScratchPluginsPrefixTree* self,
                                    const gchar* word)
{
	gint _tmp0_;
	gint _tmp1_;
	ScratchPluginsPrefixNode* _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (word != NULL);
	_tmp0_ = strlen (word);
	_tmp1_ = _tmp0_;
	if (_tmp1_ == 0) {
		return;
	}
	_tmp2_ = self->priv->root;
	scratch_plugins_prefix_tree_insert_at (self, word, _tmp2_, 0);
}

static gboolean
string_get_next_char (const gchar* self,
                      gint* index,
                      gunichar* c)
{
	gunichar _vala_c = 0U;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_vala_c = g_utf8_get_char (((gchar*) self) + (*index));
	if (_vala_c != ((gunichar) 0)) {
		gchar* _tmp0_;
		_tmp0_ = g_utf8_next_char (((gchar*) self) + (*index));
		*index = (gint) (_tmp0_ - ((gchar*) self));
		result = TRUE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	} else {
		result = FALSE;
		if (c) {
			*c = _vala_c;
		}
		return result;
	}
}

static gint
__lambda4_ (ScratchPluginsPrefixTree* self,
            ScratchPluginsPrefixNode* c1,
            ScratchPluginsPrefixNode* c2)
{
	gunichar _tmp0_;
	gunichar _tmp1_;
	gunichar _tmp2_;
	gunichar _tmp3_;
	gint result;
	g_return_val_if_fail (c1 != NULL, -1);
	g_return_val_if_fail (c2 != NULL, -1);
	_tmp0_ = scratch_plugins_prefix_node_get_value (c1);
	_tmp1_ = _tmp0_;
	_tmp2_ = scratch_plugins_prefix_node_get_value (c2);
	_tmp3_ = _tmp2_;
	if (_tmp1_ > _tmp3_) {
		result = 1;
		return result;
	} else {
		gunichar _tmp4_;
		gunichar _tmp5_;
		gunichar _tmp6_;
		gunichar _tmp7_;
		_tmp4_ = scratch_plugins_prefix_node_get_value (c1);
		_tmp5_ = _tmp4_;
		_tmp6_ = scratch_plugins_prefix_node_get_value (c2);
		_tmp7_ = _tmp6_;
		if (_tmp5_ == _tmp7_) {
			result = 0;
			return result;
		}
	}
	result = -1;
	return result;
}

static gint
___lambda4__gcompare_data_func (gconstpointer a,
                                gconstpointer b,
                                gpointer self)
{
	gint result;
	result = __lambda4_ ((ScratchPluginsPrefixTree*) self, (ScratchPluginsPrefixNode*) a, (ScratchPluginsPrefixNode*) b);
	return result;
}

static void
scratch_plugins_prefix_tree_insert_at (ScratchPluginsPrefixTree* self,
                                       const gchar* word,
                                       ScratchPluginsPrefixNode* node,
                                       gint i)
{
	gunichar curr = 0U;
	gboolean has_next_character = FALSE;
	ScratchPluginsPrefixNode* new_child = NULL;
	ScratchPluginsPrefixNode* _tmp16_;
	GeeArrayList* _tmp17_;
	ScratchPluginsPrefixNode* _tmp18_;
	GeeArrayList* _tmp19_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (word != NULL);
	g_return_if_fail (node != NULL);
	curr = (gunichar) '\0';
	has_next_character = FALSE;
	{
		gboolean _tmp0_ = FALSE;
		_tmp0_ = TRUE;
		while (TRUE) {
			gunichar _tmp2_ = 0U;
			gboolean _tmp3_;
			if (!_tmp0_) {
				gboolean _tmp1_ = FALSE;
				if (has_next_character) {
					_tmp1_ = euclide_completion_parser_is_delimiter (curr);
				} else {
					_tmp1_ = FALSE;
				}
				if (!_tmp1_) {
					break;
				}
			}
			_tmp0_ = FALSE;
			_tmp3_ = string_get_next_char (word, &i, &_tmp2_);
			curr = _tmp2_;
			has_next_character = _tmp3_;
		}
	}
	{
		GeeArrayList* _child_list = NULL;
		GeeArrayList* _tmp4_;
		gint _child_size = 0;
		GeeArrayList* _tmp5_;
		gint _tmp6_;
		gint _tmp7_;
		gint _child_index = 0;
		_tmp4_ = node->children;
		_child_list = _tmp4_;
		_tmp5_ = _child_list;
		_tmp6_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp5_);
		_tmp7_ = _tmp6_;
		_child_size = _tmp7_;
		_child_index = -1;
		while (TRUE) {
			gint _tmp8_;
			gint _tmp9_;
			ScratchPluginsPrefixNode* child = NULL;
			GeeArrayList* _tmp10_;
			gpointer _tmp11_;
			ScratchPluginsPrefixNode* _tmp12_;
			gunichar _tmp13_;
			gunichar _tmp14_;
			_child_index = _child_index + 1;
			_tmp8_ = _child_index;
			_tmp9_ = _child_size;
			if (!(_tmp8_ < _tmp9_)) {
				break;
			}
			_tmp10_ = _child_list;
			_tmp11_ = gee_abstract_list_get ((GeeAbstractList*) _tmp10_, _child_index);
			child = (ScratchPluginsPrefixNode*) _tmp11_;
			_tmp12_ = child;
			_tmp13_ = scratch_plugins_prefix_node_get_value (_tmp12_);
			_tmp14_ = _tmp13_;
			if (_tmp14_ == curr) {
				if (curr != ((gunichar) '\0')) {
					ScratchPluginsPrefixNode* _tmp15_;
					_tmp15_ = child;
					scratch_plugins_prefix_tree_insert_at (self, word, _tmp15_, i);
				}
				_g_object_unref0 (child);
				return;
			}
			_g_object_unref0 (child);
		}
	}
	_tmp16_ = scratch_plugins_prefix_node_new_from_unichar (curr, NULL);
	new_child = _tmp16_;
	_tmp17_ = node->children;
	_tmp18_ = new_child;
	gee_abstract_list_insert ((GeeAbstractList*) _tmp17_, 0, _tmp18_);
	_tmp19_ = node->children;
	gee_list_sort ((GeeList*) _tmp19_, ___lambda4__gcompare_data_func, g_object_ref (self), g_object_unref);
	if (curr != ((gunichar) '\0')) {
		ScratchPluginsPrefixNode* _tmp20_;
		_tmp20_ = new_child;
		scratch_plugins_prefix_tree_insert_at (self, word, _tmp20_, i);
	}
	_g_object_unref0 (new_child);
}

gboolean
scratch_plugins_prefix_tree_find_prefix (ScratchPluginsPrefixTree* self,
                                         const gchar* prefix)
{
	gboolean _tmp0_ = FALSE;
	ScratchPluginsPrefixNode* _tmp1_;
	ScratchPluginsPrefixNode* _tmp2_;
	ScratchPluginsPrefixNode* _tmp3_;
	gboolean _tmp4_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (prefix != NULL, FALSE);
	_tmp1_ = self->priv->root;
	_tmp2_ = scratch_plugins_prefix_tree_find_prefix_at (self, prefix, _tmp1_, 0);
	_tmp3_ = _tmp2_;
	_tmp4_ = _tmp3_ != NULL;
	_g_object_unref0 (_tmp3_);
	if (_tmp4_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static ScratchPluginsPrefixNode*
scratch_plugins_prefix_tree_find_prefix_at (ScratchPluginsPrefixTree* self,
                                            const gchar* prefix,
                                            ScratchPluginsPrefixNode* node,
                                            gint i)
{
	gunichar curr = 0U;
	gunichar _tmp0_ = 0U;
	ScratchPluginsPrefixNode* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (prefix != NULL, NULL);
	g_return_val_if_fail (node != NULL, NULL);
	string_get_next_char (prefix, &i, &_tmp0_);
	curr = _tmp0_;
	if (curr == ((gunichar) '\0')) {
		ScratchPluginsPrefixNode* _tmp1_;
		_tmp1_ = _g_object_ref0 (node);
		result = _tmp1_;
		return result;
	}
	{
		GeeArrayList* _child_list = NULL;
		GeeArrayList* _tmp2_;
		gint _child_size = 0;
		GeeArrayList* _tmp3_;
		gint _tmp4_;
		gint _tmp5_;
		gint _child_index = 0;
		_tmp2_ = node->children;
		_child_list = _tmp2_;
		_tmp3_ = _child_list;
		_tmp4_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp3_);
		_tmp5_ = _tmp4_;
		_child_size = _tmp5_;
		_child_index = -1;
		while (TRUE) {
			gint _tmp6_;
			gint _tmp7_;
			ScratchPluginsPrefixNode* child = NULL;
			GeeArrayList* _tmp8_;
			gpointer _tmp9_;
			ScratchPluginsPrefixNode* _tmp10_;
			gunichar _tmp11_;
			gunichar _tmp12_;
			_child_index = _child_index + 1;
			_tmp6_ = _child_index;
			_tmp7_ = _child_size;
			if (!(_tmp6_ < _tmp7_)) {
				break;
			}
			_tmp8_ = _child_list;
			_tmp9_ = gee_abstract_list_get ((GeeAbstractList*) _tmp8_, _child_index);
			child = (ScratchPluginsPrefixNode*) _tmp9_;
			_tmp10_ = child;
			_tmp11_ = scratch_plugins_prefix_node_get_value (_tmp10_);
			_tmp12_ = _tmp11_;
			if (_tmp12_ == curr) {
				ScratchPluginsPrefixNode* _tmp13_;
				ScratchPluginsPrefixNode* _tmp14_;
				_tmp13_ = child;
				_tmp14_ = scratch_plugins_prefix_tree_find_prefix_at (self, prefix, _tmp13_, i);
				result = _tmp14_;
				_g_object_unref0 (child);
				return result;
			}
			_g_object_unref0 (child);
		}
	}
	result = NULL;
	return result;
}

GList*
scratch_plugins_prefix_tree_get_all_matches (ScratchPluginsPrefixTree* self,
                                             const gchar* prefix)
{
	GList* list = NULL;
	ScratchPluginsPrefixNode* node = NULL;
	ScratchPluginsPrefixNode* _tmp0_;
	ScratchPluginsPrefixNode* _tmp1_;
	ScratchPluginsPrefixNode* _tmp2_;
	GList* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (prefix != NULL, NULL);
	list = NULL;
	_tmp0_ = self->priv->root;
	_tmp1_ = scratch_plugins_prefix_tree_find_prefix_at (self, prefix, _tmp0_, 0);
	node = _tmp1_;
	_tmp2_ = node;
	if (_tmp2_ != NULL) {
		GString* sb = NULL;
		GString* _tmp3_;
		ScratchPluginsPrefixNode* _tmp4_;
		_tmp3_ = g_string_new (prefix);
		sb = _tmp3_;
		_tmp4_ = node;
		scratch_plugins_prefix_tree_get_all_matches_rec (self, _tmp4_, &sb, &list);
		_g_string_free0 (sb);
	}
	result = list;
	_g_object_unref0 (node);
	return result;
}

static gchar*
g_unichar_to_string (gunichar self)
{
	gchar* str = NULL;
	gchar* _tmp0_;
	gchar* result;
	_tmp0_ = g_new0 (gchar, 7);
	str = (gchar*) _tmp0_;
	g_unichar_to_utf8 (self, str);
	result = str;
	return result;
}

static void
scratch_plugins_prefix_tree_get_all_matches_rec (ScratchPluginsPrefixTree* self,
                                                 ScratchPluginsPrefixNode* node,
                                                 GString** sbuilder,
                                                 GList** matches)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (node != NULL);
	g_return_if_fail (*sbuilder != NULL);
	{
		GeeArrayList* _child_list = NULL;
		GeeArrayList* _tmp0_;
		gint _child_size = 0;
		GeeArrayList* _tmp1_;
		gint _tmp2_;
		gint _tmp3_;
		gint _child_index = 0;
		_tmp0_ = node->children;
		_child_list = _tmp0_;
		_tmp1_ = _child_list;
		_tmp2_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp1_);
		_tmp3_ = _tmp2_;
		_child_size = _tmp3_;
		_child_index = -1;
		while (TRUE) {
			gint _tmp4_;
			gint _tmp5_;
			ScratchPluginsPrefixNode* child = NULL;
			GeeArrayList* _tmp6_;
			gpointer _tmp7_;
			ScratchPluginsPrefixNode* _tmp8_;
			gunichar _tmp9_;
			gunichar _tmp10_;
			_child_index = _child_index + 1;
			_tmp4_ = _child_index;
			_tmp5_ = _child_size;
			if (!(_tmp4_ < _tmp5_)) {
				break;
			}
			_tmp6_ = _child_list;
			_tmp7_ = gee_abstract_list_get ((GeeAbstractList*) _tmp6_, _child_index);
			child = (ScratchPluginsPrefixNode*) _tmp7_;
			_tmp8_ = child;
			_tmp9_ = scratch_plugins_prefix_node_get_value (_tmp8_);
			_tmp10_ = _tmp9_;
			if (_tmp10_ == ((gunichar) '\0')) {
				const gchar* _tmp11_;
				gchar* _tmp12_;
				_tmp11_ = (*sbuilder)->str;
				_tmp12_ = g_strdup (_tmp11_);
				*matches = g_list_append (*matches, _tmp12_);
			} else {
				ScratchPluginsPrefixNode* _tmp13_;
				gunichar _tmp14_;
				gunichar _tmp15_;
				ScratchPluginsPrefixNode* _tmp16_;
				gint length = 0;
				ScratchPluginsPrefixNode* _tmp17_;
				gunichar _tmp18_;
				gunichar _tmp19_;
				gchar* _tmp20_;
				gchar* _tmp21_;
				gint _tmp22_;
				gint _tmp23_;
				gint _tmp24_;
				_tmp13_ = child;
				_tmp14_ = scratch_plugins_prefix_node_get_value (_tmp13_);
				_tmp15_ = _tmp14_;
				g_string_append_unichar (*sbuilder, _tmp15_);
				_tmp16_ = child;
				scratch_plugins_prefix_tree_get_all_matches_rec (self, _tmp16_, sbuilder, matches);
				_tmp17_ = child;
				_tmp18_ = scratch_plugins_prefix_node_get_value (_tmp17_);
				_tmp19_ = _tmp18_;
				_tmp20_ = g_unichar_to_string (_tmp19_);
				_tmp21_ = _tmp20_;
				_tmp22_ = strlen (_tmp21_);
				_tmp23_ = _tmp22_;
				_tmp24_ = _tmp23_;
				_g_free0 (_tmp21_);
				length = _tmp24_;
				g_string_erase (*sbuilder, (*sbuilder)->len - length, (gssize) -1);
			}
			_g_object_unref0 (child);
		}
	}
}

ScratchPluginsPrefixTree*
scratch_plugins_prefix_tree_construct (GType object_type)
{
	ScratchPluginsPrefixTree * self = NULL;
	self = (ScratchPluginsPrefixTree*) g_object_new (object_type, NULL);
	return self;
}

ScratchPluginsPrefixTree*
scratch_plugins_prefix_tree_new (void)
{
	return scratch_plugins_prefix_tree_construct (SCRATCH_PLUGINS_TYPE_PREFIX_TREE);
}

static GObject *
scratch_plugins_prefix_tree_constructor (GType type,
                                         guint n_construct_properties,
                                         GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	ScratchPluginsPrefixTree * self;
	parent_class = G_OBJECT_CLASS (scratch_plugins_prefix_tree_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SCRATCH_PLUGINS_TYPE_PREFIX_TREE, ScratchPluginsPrefixTree);
	scratch_plugins_prefix_tree_clear (self);
	return obj;
}

static void
scratch_plugins_prefix_tree_class_init (ScratchPluginsPrefixTreeClass * klass,
                                        gpointer klass_data)
{
	scratch_plugins_prefix_tree_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ScratchPluginsPrefixTree_private_offset);
	G_OBJECT_CLASS (klass)->constructor = scratch_plugins_prefix_tree_constructor;
	G_OBJECT_CLASS (klass)->finalize = scratch_plugins_prefix_tree_finalize;
}

static void
scratch_plugins_prefix_tree_instance_init (ScratchPluginsPrefixTree * self,
                                           gpointer klass)
{
	self->priv = scratch_plugins_prefix_tree_get_instance_private (self);
}

static void
scratch_plugins_prefix_tree_finalize (GObject * obj)
{
	ScratchPluginsPrefixTree * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SCRATCH_PLUGINS_TYPE_PREFIX_TREE, ScratchPluginsPrefixTree);
	_g_object_unref0 (self->priv->root);
	G_OBJECT_CLASS (scratch_plugins_prefix_tree_parent_class)->finalize (obj);
}

GType
scratch_plugins_prefix_tree_get_type (void)
{
	return scratch_plugins_prefix_tree_type_id;
}

GType
scratch_plugins_prefix_tree_register_type (GTypeModule * module)
{
	static const GTypeInfo g_define_type_info = { sizeof (ScratchPluginsPrefixTreeClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) scratch_plugins_prefix_tree_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ScratchPluginsPrefixTree), 0, (GInstanceInitFunc) scratch_plugins_prefix_tree_instance_init, NULL };
	scratch_plugins_prefix_tree_type_id = g_type_module_register_type (module, G_TYPE_OBJECT, "ScratchPluginsPrefixTree", &g_define_type_info, G_TYPE_FLAG_NONE);
	ScratchPluginsPrefixTree_private_offset = sizeof (ScratchPluginsPrefixTreePrivate);
	return scratch_plugins_prefix_tree_type_id;
}

