/* utils.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from utils.vala, do not modify */

/*
 * Copyright (C) 2011 Collabora Ltd.
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *       Raul Gutierrez Segales <raul.gutierrez.segales@collabora.co.uk>
 *       Travis Reitter <travis.reitter@collabora.co.uk>
 */

#include "folks/folks.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include <gee.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  {
	FOLKS_UTILS_0_PROPERTY,
	FOLKS_UTILS_NUM_PROPERTIES
};
static GParamSpec* folks_utils_properties[FOLKS_UTILS_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

static gpointer folks_utils_parent_class = NULL;

VALA_EXTERN gboolean _folks_utils_str_equal_safe (const gchar* a,
                                      const gchar* b);
static GType folks_utils_get_type_once (void);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

gboolean
_folks_utils_str_equal_safe (const gchar* a,
                             const gchar* b)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	if (g_strcmp0 (a, "") != 0) {
		_tmp1_ = g_strcmp0 (b, "") != 0;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		gchar* _tmp2_;
		gchar* _tmp3_;
		gchar* _tmp4_;
		gchar* _tmp5_;
		_tmp2_ = g_utf8_strdown (a, (gssize) -1);
		_tmp3_ = _tmp2_;
		_tmp4_ = g_utf8_strdown (b, (gssize) -1);
		_tmp5_ = _tmp4_;
		_tmp0_ = g_strcmp0 (_tmp3_, _tmp5_) == 0;
		_g_free0 (_tmp5_);
		_g_free0 (_tmp3_);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

/**
   * Create a new utilities object.
   *
   * This method is useless and should never be used. It will be removed in a
   * future version in favour of making the Utils class into a nested namespace.
   *
   * @return a new utilities object
   * @since 0.6.0
   */
FolksUtils*
folks_utils_construct (GType object_type)
{
	FolksUtils * self = NULL;
	self = (FolksUtils*) g_object_new (object_type, NULL);
	return self;
}

FolksUtils*
folks_utils_new (void)
{
	return folks_utils_construct (FOLKS_TYPE_UTILS);
}

/**
   * Check whether two multi-maps of strings to strings are equal. This performs
   * a deep check for equality, checking whether both maps are of the same size,
   * and that each key maps to the same set of values in both maps.
   *
   * @param a a multi-map to compare
   * @param b another multi-map to compare
   * @return ``true`` if the multi-maps are equal, ``false`` otherwise
   *
   * @since 0.6.0
   */
gboolean
folks_utils_multi_map_str_str_equal (GeeMultiMap* a,
                                     GeeMultiMap* b)
{
	gint a_size = 0;
	gint _tmp0_;
	gint _tmp1_;
	gint b_size = 0;
	gint _tmp2_;
	gint _tmp3_;
	gboolean _tmp4_ = FALSE;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	if (a == b) {
		result = TRUE;
		return result;
	}
	_tmp0_ = gee_multi_map_get_size (a);
	_tmp1_ = _tmp0_;
	a_size = _tmp1_;
	_tmp2_ = gee_multi_map_get_size (b);
	_tmp3_ = _tmp2_;
	b_size = _tmp3_;
	if (a_size == 0) {
		_tmp4_ = b_size == 0;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		result = TRUE;
		return result;
	} else {
		if (a_size == b_size) {
			{
				GeeIterator* _key_it = NULL;
				GeeSet* _tmp5_;
				GeeSet* _tmp6_;
				GeeIterator* _tmp7_;
				GeeIterator* _tmp8_;
				_tmp5_ = gee_multi_map_get_keys (a);
				_tmp6_ = _tmp5_;
				_tmp7_ = gee_iterable_iterator ((GeeIterable*) _tmp6_);
				_tmp8_ = _tmp7_;
				_g_object_unref0 (_tmp6_);
				_key_it = _tmp8_;
				while (TRUE) {
					GeeIterator* _tmp9_;
					gchar* key = NULL;
					GeeIterator* _tmp10_;
					gpointer _tmp11_;
					const gchar* _tmp12_;
					_tmp9_ = _key_it;
					if (!gee_iterator_next (_tmp9_)) {
						break;
					}
					_tmp10_ = _key_it;
					_tmp11_ = gee_iterator_get (_tmp10_);
					key = (gchar*) _tmp11_;
					_tmp12_ = key;
					if (gee_multi_map_contains (b, _tmp12_)) {
						GeeCollection* a_values = NULL;
						const gchar* _tmp13_;
						GeeCollection* _tmp14_;
						GeeCollection* b_values = NULL;
						const gchar* _tmp15_;
						GeeCollection* _tmp16_;
						GeeCollection* _tmp17_;
						gint _tmp18_;
						gint _tmp19_;
						GeeCollection* _tmp20_;
						gint _tmp21_;
						gint _tmp22_;
						_tmp13_ = key;
						_tmp14_ = gee_multi_map_get (a, _tmp13_);
						a_values = _tmp14_;
						_tmp15_ = key;
						_tmp16_ = gee_multi_map_get (b, _tmp15_);
						b_values = _tmp16_;
						_tmp17_ = a_values;
						_tmp18_ = gee_collection_get_size (_tmp17_);
						_tmp19_ = _tmp18_;
						_tmp20_ = b_values;
						_tmp21_ = gee_collection_get_size (_tmp20_);
						_tmp22_ = _tmp21_;
						if (_tmp19_ != _tmp22_) {
							result = FALSE;
							_g_object_unref0 (b_values);
							_g_object_unref0 (a_values);
							_g_free0 (key);
							_g_object_unref0 (_key_it);
							return result;
						}
						{
							GeeIterator* _a_value_it = NULL;
							GeeCollection* _tmp23_;
							GeeIterator* _tmp24_;
							_tmp23_ = a_values;
							_tmp24_ = gee_iterable_iterator ((GeeIterable*) _tmp23_);
							_a_value_it = _tmp24_;
							while (TRUE) {
								GeeIterator* _tmp25_;
								gchar* a_value = NULL;
								GeeIterator* _tmp26_;
								gpointer _tmp27_;
								GeeCollection* _tmp28_;
								const gchar* _tmp29_;
								_tmp25_ = _a_value_it;
								if (!gee_iterator_next (_tmp25_)) {
									break;
								}
								_tmp26_ = _a_value_it;
								_tmp27_ = gee_iterator_get (_tmp26_);
								a_value = (gchar*) _tmp27_;
								_tmp28_ = b_values;
								_tmp29_ = a_value;
								if (!gee_collection_contains (_tmp28_, _tmp29_)) {
									result = FALSE;
									_g_free0 (a_value);
									_g_object_unref0 (_a_value_it);
									_g_object_unref0 (b_values);
									_g_object_unref0 (a_values);
									_g_free0 (key);
									_g_object_unref0 (_key_it);
									return result;
								}
								_g_free0 (a_value);
							}
							_g_object_unref0 (_a_value_it);
						}
						_g_object_unref0 (b_values);
						_g_object_unref0 (a_values);
					} else {
						result = FALSE;
						_g_free0 (key);
						_g_object_unref0 (_key_it);
						return result;
					}
					_g_free0 (key);
				}
				_g_object_unref0 (_key_it);
			}
		} else {
			result = FALSE;
			return result;
		}
	}
	result = TRUE;
	return result;
}

/**
   * Check whether two multi-maps of strings to AbstractFieldDetails are equal.
   *
   * This performs a deep check for equality, checking whether both maps are of
   * the same size, and that each key maps to the same set of values in both
   * maps.
   *
   * @param a a multi-map to compare
   * @param b another multi-map to compare
   * @return ``true`` if the multi-maps are equal, ``false`` otherwise
   *
   * @since 0.6.0
   */
gboolean
folks_utils_multi_map_str_afd_equal (GeeMultiMap* a,
                                     GeeMultiMap* b)
{
	gint a_size = 0;
	gint _tmp0_;
	gint _tmp1_;
	gint b_size = 0;
	gint _tmp2_;
	gint _tmp3_;
	gboolean _tmp4_ = FALSE;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	if (a == b) {
		result = TRUE;
		return result;
	}
	_tmp0_ = gee_multi_map_get_size (a);
	_tmp1_ = _tmp0_;
	a_size = _tmp1_;
	_tmp2_ = gee_multi_map_get_size (b);
	_tmp3_ = _tmp2_;
	b_size = _tmp3_;
	if (a_size == 0) {
		_tmp4_ = b_size == 0;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		result = TRUE;
		return result;
	} else {
		if (a_size == b_size) {
			{
				GeeIterator* _key_it = NULL;
				GeeSet* _tmp5_;
				GeeSet* _tmp6_;
				GeeIterator* _tmp7_;
				GeeIterator* _tmp8_;
				_tmp5_ = gee_multi_map_get_keys (a);
				_tmp6_ = _tmp5_;
				_tmp7_ = gee_iterable_iterator ((GeeIterable*) _tmp6_);
				_tmp8_ = _tmp7_;
				_g_object_unref0 (_tmp6_);
				_key_it = _tmp8_;
				while (TRUE) {
					GeeIterator* _tmp9_;
					gchar* key = NULL;
					GeeIterator* _tmp10_;
					gpointer _tmp11_;
					const gchar* _tmp12_;
					_tmp9_ = _key_it;
					if (!gee_iterator_next (_tmp9_)) {
						break;
					}
					_tmp10_ = _key_it;
					_tmp11_ = gee_iterator_get (_tmp10_);
					key = (gchar*) _tmp11_;
					_tmp12_ = key;
					if (gee_multi_map_contains (b, _tmp12_)) {
						GeeCollection* a_values = NULL;
						const gchar* _tmp13_;
						GeeCollection* _tmp14_;
						GeeCollection* b_values = NULL;
						const gchar* _tmp15_;
						GeeCollection* _tmp16_;
						GeeCollection* _tmp17_;
						gint _tmp18_;
						gint _tmp19_;
						GeeCollection* _tmp20_;
						gint _tmp21_;
						gint _tmp22_;
						_tmp13_ = key;
						_tmp14_ = gee_multi_map_get (a, _tmp13_);
						a_values = _tmp14_;
						_tmp15_ = key;
						_tmp16_ = gee_multi_map_get (b, _tmp15_);
						b_values = _tmp16_;
						_tmp17_ = a_values;
						_tmp18_ = gee_collection_get_size (_tmp17_);
						_tmp19_ = _tmp18_;
						_tmp20_ = b_values;
						_tmp21_ = gee_collection_get_size (_tmp20_);
						_tmp22_ = _tmp21_;
						if (_tmp19_ != _tmp22_) {
							result = FALSE;
							_g_object_unref0 (b_values);
							_g_object_unref0 (a_values);
							_g_free0 (key);
							_g_object_unref0 (_key_it);
							return result;
						}
						{
							GeeIterator* _a_value_it = NULL;
							GeeCollection* _tmp23_;
							GeeIterator* _tmp24_;
							_tmp23_ = a_values;
							_tmp24_ = gee_iterable_iterator ((GeeIterable*) _tmp23_);
							_a_value_it = _tmp24_;
							while (TRUE) {
								GeeIterator* _tmp25_;
								FolksAbstractFieldDetails* a_value = NULL;
								GeeIterator* _tmp26_;
								gpointer _tmp27_;
								GeeCollection* _tmp28_;
								FolksAbstractFieldDetails* _tmp29_;
								_tmp25_ = _a_value_it;
								if (!gee_iterator_next (_tmp25_)) {
									break;
								}
								_tmp26_ = _a_value_it;
								_tmp27_ = gee_iterator_get (_tmp26_);
								a_value = (FolksAbstractFieldDetails*) _tmp27_;
								_tmp28_ = b_values;
								_tmp29_ = a_value;
								if (!gee_collection_contains (_tmp28_, _tmp29_)) {
									result = FALSE;
									_g_object_unref0 (a_value);
									_g_object_unref0 (_a_value_it);
									_g_object_unref0 (b_values);
									_g_object_unref0 (a_values);
									_g_free0 (key);
									_g_object_unref0 (_key_it);
									return result;
								}
								_g_object_unref0 (a_value);
							}
							_g_object_unref0 (_a_value_it);
						}
						_g_object_unref0 (b_values);
						_g_object_unref0 (a_values);
					} else {
						result = FALSE;
						_g_free0 (key);
						_g_object_unref0 (_key_it);
						return result;
					}
					_g_free0 (key);
				}
				_g_object_unref0 (_key_it);
			}
		} else {
			result = FALSE;
			return result;
		}
	}
	result = TRUE;
	return result;
}

/**
   * Check whether a set of strings to AbstractFieldDetails are equal.
   *
   * This performs a deep check for equality, checking whether both sets are of
   * the same size, and that each key maps to the same set of values in both
   * maps.
   *
   * @param a a set to compare
   * @param b another set to compare
   * @return ``true`` if the sets are equal, ``false`` otherwise
   *
   * @since 0.6.0
   */
gboolean
folks_utils_set_afd_equal (GeeSet* a,
                           GeeSet* b)
{
	gint a_size = 0;
	gint _tmp0_;
	gint _tmp1_;
	gint b_size = 0;
	gint _tmp2_;
	gint _tmp3_;
	gboolean _tmp4_ = FALSE;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	if (a == b) {
		result = TRUE;
		return result;
	}
	_tmp0_ = gee_collection_get_size ((GeeCollection*) a);
	_tmp1_ = _tmp0_;
	a_size = _tmp1_;
	_tmp2_ = gee_collection_get_size ((GeeCollection*) b);
	_tmp3_ = _tmp2_;
	b_size = _tmp3_;
	if (a_size == 0) {
		_tmp4_ = b_size == 0;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		result = TRUE;
		return result;
	} else {
		if (a_size == b_size) {
			{
				GeeIterator* _val_it = NULL;
				GeeIterator* _tmp5_;
				_tmp5_ = gee_iterable_iterator ((GeeIterable*) a);
				_val_it = _tmp5_;
				while (TRUE) {
					GeeIterator* _tmp6_;
					FolksAbstractFieldDetails* val = NULL;
					GeeIterator* _tmp7_;
					gpointer _tmp8_;
					FolksAbstractFieldDetails* _tmp9_;
					_tmp6_ = _val_it;
					if (!gee_iterator_next (_tmp6_)) {
						break;
					}
					_tmp7_ = _val_it;
					_tmp8_ = gee_iterator_get (_tmp7_);
					val = (FolksAbstractFieldDetails*) _tmp8_;
					_tmp9_ = val;
					if (!gee_collection_contains ((GeeCollection*) b, _tmp9_)) {
						result = FALSE;
						_g_object_unref0 (val);
						_g_object_unref0 (_val_it);
						return result;
					}
					_g_object_unref0 (val);
				}
				_g_object_unref0 (_val_it);
			}
		} else {
			result = FALSE;
			return result;
		}
	}
	result = TRUE;
	return result;
}

/**
   * Check whether a set of AbstractFieldDetails with string values are equal.
   *
   * This performs a deep check for equality, checking whether both sets are of
   * the same size, and that each set has the same values using string compaction
   * instead of AbstractFieldDetails equal function
   *
   * @param a a set to compare
   * @param b another set to compare
   * @return ``true`` if the sets are equal, ``false`` otherwise
   *
   * @since 0.9.7
   */
gboolean
folks_utils_set_string_afd_equal (GeeSet* a,
                                  GeeSet* b)
{
	gint a_size = 0;
	gint _tmp0_;
	gint _tmp1_;
	gint b_size = 0;
	gint _tmp2_;
	gint _tmp3_;
	gboolean _tmp4_ = FALSE;
	gboolean result;
	g_return_val_if_fail (a != NULL, FALSE);
	g_return_val_if_fail (b != NULL, FALSE);
	if (a == b) {
		result = TRUE;
		return result;
	}
	_tmp0_ = gee_collection_get_size ((GeeCollection*) a);
	_tmp1_ = _tmp0_;
	a_size = _tmp1_;
	_tmp2_ = gee_collection_get_size ((GeeCollection*) b);
	_tmp3_ = _tmp2_;
	b_size = _tmp3_;
	if (a_size == 0) {
		_tmp4_ = b_size == 0;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		result = TRUE;
		return result;
	} else {
		if (a_size == b_size) {
			{
				GeeIterator* _a_val_it = NULL;
				GeeIterator* _tmp5_;
				_tmp5_ = gee_iterable_iterator ((GeeIterable*) a);
				_a_val_it = _tmp5_;
				while (TRUE) {
					GeeIterator* _tmp6_;
					FolksAbstractFieldDetails* a_val = NULL;
					GeeIterator* _tmp7_;
					gpointer _tmp8_;
					gboolean found = FALSE;
					_tmp6_ = _a_val_it;
					if (!gee_iterator_next (_tmp6_)) {
						break;
					}
					_tmp7_ = _a_val_it;
					_tmp8_ = gee_iterator_get (_tmp7_);
					a_val = (FolksAbstractFieldDetails*) _tmp8_;
					found = FALSE;
					{
						GeeIterator* _b_val_it = NULL;
						GeeIterator* _tmp9_;
						_tmp9_ = gee_iterable_iterator ((GeeIterable*) b);
						_b_val_it = _tmp9_;
						while (TRUE) {
							GeeIterator* _tmp10_;
							FolksAbstractFieldDetails* b_val = NULL;
							GeeIterator* _tmp11_;
							gpointer _tmp12_;
							gboolean _tmp13_ = FALSE;
							FolksAbstractFieldDetails* _tmp14_;
							FolksAbstractFieldDetails* _tmp15_;
							_tmp10_ = _b_val_it;
							if (!gee_iterator_next (_tmp10_)) {
								break;
							}
							_tmp11_ = _b_val_it;
							_tmp12_ = gee_iterator_get (_tmp11_);
							b_val = (FolksAbstractFieldDetails*) _tmp12_;
							_tmp14_ = a_val;
							_tmp15_ = b_val;
							if (folks_abstract_field_details_parameters_equal (_tmp14_, _tmp15_)) {
								GEqualFunc _tmp16_;
								FolksAbstractFieldDetails* _tmp17_;
								gconstpointer _tmp18_;
								gconstpointer _tmp19_;
								FolksAbstractFieldDetails* _tmp20_;
								gconstpointer _tmp21_;
								gconstpointer _tmp22_;
								_tmp16_ = g_str_equal;
								_tmp17_ = a_val;
								_tmp18_ = folks_abstract_field_details_get_value (_tmp17_);
								_tmp19_ = _tmp18_;
								_tmp20_ = b_val;
								_tmp21_ = folks_abstract_field_details_get_value (_tmp20_);
								_tmp22_ = _tmp21_;
								_tmp13_ = _tmp16_ ((const gchar*) _tmp19_, (const gchar*) _tmp22_);
							} else {
								_tmp13_ = FALSE;
							}
							if (_tmp13_) {
								found = TRUE;
							}
							_g_object_unref0 (b_val);
						}
						_g_object_unref0 (_b_val_it);
					}
					if (!found) {
						result = FALSE;
						_g_object_unref0 (a_val);
						_g_object_unref0 (_a_val_it);
						return result;
					}
					_g_object_unref0 (a_val);
				}
				_g_object_unref0 (_a_val_it);
			}
		} else {
			result = FALSE;
			return result;
		}
	}
	result = TRUE;
	return result;
}

static void
folks_utils_class_init (FolksUtilsClass * klass,
                        gpointer klass_data)
{
	folks_utils_parent_class = g_type_class_peek_parent (klass);
}

static void
folks_utils_instance_init (FolksUtils * self,
                           gpointer klass)
{
}

/**
 * Utility functions to simplify common patterns in Folks client code.
 *
 * These may be used by folks clients as well, and are part of folks' supported
 * stable API.
 *
 * @since 0.6.0
 */
static GType
folks_utils_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FolksUtilsClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) folks_utils_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FolksUtils), 0, (GInstanceInitFunc) folks_utils_instance_init, NULL };
	GType folks_utils_type_id;
	folks_utils_type_id = g_type_register_static (G_TYPE_OBJECT, "FolksUtils", &g_define_type_info, 0);
	return folks_utils_type_id;
}

GType
folks_utils_get_type (void)
{
	static volatile gsize folks_utils_type_id__once = 0;
	if (g_once_init_enter (&folks_utils_type_id__once)) {
		GType folks_utils_type_id;
		folks_utils_type_id = folks_utils_get_type_once ();
		g_once_init_leave (&folks_utils_type_id__once, folks_utils_type_id);
	}
	return folks_utils_type_id__once;
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

