/* geary-email-identifier.c generated by valac 0.56.3, the Vala compiler
 * generated from geary-email-identifier.vala, do not modify */

/*
 * Copyright 2016 Software Freedom Conservancy Inc.
 * Copyright 2019 Michael Gratton <mike@vee.net>.
 *
 * This software is licensed under the GNU Lesser General Public License
 * (version 2.1 or later). See the COPYING file in this distribution.
 */

#include "geary-engine.h"
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <gee.h>
#include <glib-object.h>

enum  {
	GEARY_EMAIL_IDENTIFIER_0_PROPERTY,
	GEARY_EMAIL_IDENTIFIER_NUM_PROPERTIES
};
static GParamSpec* geary_email_identifier_properties[GEARY_EMAIL_IDENTIFIER_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))

static gpointer geary_email_identifier_parent_class = NULL;
static GeeHashableIface * geary_email_identifier_gee_hashable_parent_iface = NULL;

static guint geary_email_identifier_real_hash (GearyEmailIdentifier* self);
static gboolean geary_email_identifier_real_equal_to (GearyEmailIdentifier* self,
                                               GearyEmailIdentifier* other);
static GVariant* geary_email_identifier_real_to_variant (GearyEmailIdentifier* self);
static gchar* geary_email_identifier_real_to_string (GearyEmailIdentifier* self);
static gint geary_email_identifier_real_stable_sort_comparator (GearyEmailIdentifier* self,
                                                         GearyEmailIdentifier* other);
static gint geary_email_identifier_real_natural_sort_comparator (GearyEmailIdentifier* self,
                                                          GearyEmailIdentifier* other);
static gint __lambda4_ (GearyEmailIdentifier* a,
                 GearyEmailIdentifier* b);
static gint ___lambda4__gcompare_data_func (gconstpointer a,
                                     gconstpointer b,
                                     gpointer self);
static gint __lambda20_ (GearyEmail* a,
                  GearyEmail* b);
static gint ___lambda20__gcompare_data_func (gconstpointer a,
                                      gconstpointer b,
                                      gpointer self);
static GType geary_email_identifier_get_type_once (void);

/** {@inheritDoc} */
static guint
geary_email_identifier_real_hash (GearyEmailIdentifier* self)
{
	guint _tmp0_ = 0U;
	g_critical ("Type `%s' does not implement abstract method `geary_email_identifier_hash'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return _tmp0_;
}

guint
geary_email_identifier_hash (GearyEmailIdentifier* self)
{
	GearyEmailIdentifierClass* _klass_;
	g_return_val_if_fail (GEARY_IS_EMAIL_IDENTIFIER (self), 0U);
	_klass_ = GEARY_EMAIL_IDENTIFIER_GET_CLASS (self);
	if (_klass_->hash) {
		return _klass_->hash (self);
	}
	return 0U;
}

/** {@inheritDoc} */
static gboolean
geary_email_identifier_real_equal_to (GearyEmailIdentifier* self,
                                      GearyEmailIdentifier* other)
{
	gboolean _tmp0_ = FALSE;
	g_critical ("Type `%s' does not implement abstract method `geary_email_identifier_equal_to'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return _tmp0_;
}

gboolean
geary_email_identifier_equal_to (GearyEmailIdentifier* self,
                                 GearyEmailIdentifier* other)
{
	GearyEmailIdentifierClass* _klass_;
	g_return_val_if_fail (GEARY_IS_EMAIL_IDENTIFIER (self), FALSE);
	_klass_ = GEARY_EMAIL_IDENTIFIER_GET_CLASS (self);
	if (_klass_->equal_to) {
		return _klass_->equal_to (self, other);
	}
	return FALSE;
}

/**
     * Returns a representation useful for serialisation.
     *
     * This can be used to transmit ids as D-Bus method and GLib
     * Action parameters, and so on.
     *
     * @return a serialised form of this id, that will match the
     * GVariantType given by {@link BASE_VARIANT_TYPE}.
     *
     * @see Account.to_email_identifier
     */
static GVariant*
geary_email_identifier_real_to_variant (GearyEmailIdentifier* self)
{
	g_critical ("Type `%s' does not implement abstract method `geary_email_identifier_to_variant'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return NULL;
}

GVariant*
geary_email_identifier_to_variant (GearyEmailIdentifier* self)
{
	GearyEmailIdentifierClass* _klass_;
	g_return_val_if_fail (GEARY_IS_EMAIL_IDENTIFIER (self), NULL);
	_klass_ = GEARY_EMAIL_IDENTIFIER_GET_CLASS (self);
	if (_klass_->to_variant) {
		return _klass_->to_variant (self);
	}
	return NULL;
}

/**
     * Returns a representation useful for debugging.
     */
static gchar*
geary_email_identifier_real_to_string (GearyEmailIdentifier* self)
{
	g_critical ("Type `%s' does not implement abstract method `geary_email_identifier_to_string'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return NULL;
}

gchar*
geary_email_identifier_to_string (GearyEmailIdentifier* self)
{
	GearyEmailIdentifierClass* _klass_;
	g_return_val_if_fail (GEARY_IS_EMAIL_IDENTIFIER (self), NULL);
	_klass_ = GEARY_EMAIL_IDENTIFIER_GET_CLASS (self);
	if (_klass_->to_string) {
		return _klass_->to_string (self);
	}
	return NULL;
}

/**
     * A comparator for stabilizing sorts.
     *
     * This has no bearing on a "natural" sort order for EmailIdentifiers and shouldn't be used
     * to indicate such.  This is why EmailIdentifier doesn't implement the Comparable interface.
     */
static gint
geary_email_identifier_real_stable_sort_comparator (GearyEmailIdentifier* self,
                                                    GearyEmailIdentifier* other)
{
	GCompareFunc _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gint _tmp5_;
	gint result;
	g_return_val_if_fail (GEARY_IS_EMAIL_IDENTIFIER (other), 0);
	if (self == other) {
		result = 0;
		return result;
	}
	_tmp0_ = ((GCompareFunc) g_strcmp0);
	_tmp1_ = geary_email_identifier_to_string (self);
	_tmp2_ = _tmp1_;
	_tmp3_ = geary_email_identifier_to_string (other);
	_tmp4_ = _tmp3_;
	_tmp5_ = _tmp0_ (_tmp2_, _tmp4_);
	_g_free0 (_tmp4_);
	_g_free0 (_tmp2_);
	result = _tmp5_;
	return result;
}

gint
geary_email_identifier_stable_sort_comparator (GearyEmailIdentifier* self,
                                               GearyEmailIdentifier* other)
{
	GearyEmailIdentifierClass* _klass_;
	g_return_val_if_fail (GEARY_IS_EMAIL_IDENTIFIER (self), 0);
	_klass_ = GEARY_EMAIL_IDENTIFIER_GET_CLASS (self);
	if (_klass_->stable_sort_comparator) {
		return _klass_->stable_sort_comparator (self, other);
	}
	return -1;
}

/**
     * A comparator for finding which {@link EmailIdentifier} is earliest in the "natural"
     * sorting of a {@link Folder}'s list.
     *
     * This only applies for {@link Email} which is listed from a Folder; fetching or listing
     * Email from the {@link Account} has no sense of natural ordering.  Also, this should not be
     * used for EmailIdentifiers that originated from different Folders.
     *
     * Implementations should treat messages with no natural ordering (not coming from a
     * Folder) as later than than that do (i.e. returns 1).
     *
     * If both have no natural order, they are considered equal for the purposes of this method;
     * {@link stable_sort_comparator} can be used to deal with that situation.
     *
     * EmailIdentifiers that cannot be compared against this one (i.e. of a different subclass)
     * should return 1 as well.  Generally this means they came from different Folders.
     *
     * @see Folder.list_email_by_id_async
     */
static gint
geary_email_identifier_real_natural_sort_comparator (GearyEmailIdentifier* self,
                                                     GearyEmailIdentifier* other)
{
	gint _tmp0_ = 0;
	g_critical ("Type `%s' does not implement abstract method `geary_email_identifier_natural_sort_comparator'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
	return _tmp0_;
}

gint
geary_email_identifier_natural_sort_comparator (GearyEmailIdentifier* self,
                                                GearyEmailIdentifier* other)
{
	GearyEmailIdentifierClass* _klass_;
	g_return_val_if_fail (GEARY_IS_EMAIL_IDENTIFIER (self), 0);
	_klass_ = GEARY_EMAIL_IDENTIFIER_GET_CLASS (self);
	if (_klass_->natural_sort_comparator) {
		return _klass_->natural_sort_comparator (self, other);
	}
	return -1;
}

/**
     * Sorts the supplied Collection of {@link EmailIdentifier} by their natural sort order.
     *
     * This method uses {@link natural_sort_comparator}, so read its provisions about comparison.
     * In essence, this method should only be used against EmailIdentifiers that originated from
     * the same Folder.
     */
static gint
__lambda4_ (GearyEmailIdentifier* a,
            GearyEmailIdentifier* b)
{
	gint cmp = 0;
	gint result;
	g_return_val_if_fail (GEARY_IS_EMAIL_IDENTIFIER (a), 0);
	g_return_val_if_fail (GEARY_IS_EMAIL_IDENTIFIER (b), 0);
	cmp = geary_email_identifier_natural_sort_comparator (a, b);
	if (cmp == 0) {
		cmp = geary_email_identifier_stable_sort_comparator (a, b);
	}
	result = cmp;
	return result;
}

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

GeeSortedSet*
geary_email_identifier_sort (GeeCollection* ids)
{
	GeeSortedSet* sorted = NULL;
	GeeTreeSet* _tmp0_;
	GeeSortedSet* result;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (ids, GEE_TYPE_COLLECTION), NULL);
	_tmp0_ = gee_tree_set_new (GEARY_TYPE_EMAIL_IDENTIFIER, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, ___lambda4__gcompare_data_func, NULL, NULL);
	sorted = G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, GEE_TYPE_SORTED_SET, GeeSortedSet);
	gee_collection_add_all (G_TYPE_CHECK_INSTANCE_CAST (sorted, GEE_TYPE_COLLECTION, GeeCollection), ids);
	result = sorted;
	return result;
}

/**
     * Sorts the supplied Collection of {@link EmailIdentifier} by their natural sort order.
     *
     * This method uses {@link natural_sort_comparator}, so read its provisions about comparison.
     * In essence, this method should only be used against EmailIdentifiers that originated from
     * the same Folder.
     */
static gint
__lambda20_ (GearyEmail* a,
             GearyEmail* b)
{
	gint cmp = 0;
	GearyEmailIdentifier* _tmp0_;
	GearyEmailIdentifier* _tmp1_;
	GearyEmailIdentifier* _tmp2_;
	GearyEmailIdentifier* _tmp3_;
	gint result;
	g_return_val_if_fail (GEARY_IS_EMAIL (a), 0);
	g_return_val_if_fail (GEARY_IS_EMAIL (b), 0);
	_tmp0_ = geary_email_get_id (a);
	_tmp1_ = _tmp0_;
	_tmp2_ = geary_email_get_id (b);
	_tmp3_ = _tmp2_;
	cmp = geary_email_identifier_natural_sort_comparator (_tmp1_, _tmp3_);
	if (cmp == 0) {
		GearyEmailIdentifier* _tmp4_;
		GearyEmailIdentifier* _tmp5_;
		GearyEmailIdentifier* _tmp6_;
		GearyEmailIdentifier* _tmp7_;
		_tmp4_ = geary_email_get_id (a);
		_tmp5_ = _tmp4_;
		_tmp6_ = geary_email_get_id (b);
		_tmp7_ = _tmp6_;
		cmp = geary_email_identifier_stable_sort_comparator (_tmp5_, _tmp7_);
	}
	result = cmp;
	return result;
}

static gint
___lambda20__gcompare_data_func (gconstpointer a,
                                 gconstpointer b,
                                 gpointer self)
{
	gint result;
	result = __lambda20_ ((GearyEmail*) a, (GearyEmail*) b);
	return result;
}

GeeSortedSet*
geary_email_identifier_sort_emails (GeeCollection* emails)
{
	GeeSortedSet* sorted = NULL;
	GeeTreeSet* _tmp0_;
	GeeSortedSet* result;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (emails, GEE_TYPE_COLLECTION), NULL);
	_tmp0_ = gee_tree_set_new (GEARY_TYPE_EMAIL, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, ___lambda20__gcompare_data_func, NULL, NULL);
	sorted = G_TYPE_CHECK_INSTANCE_CAST (_tmp0_, GEE_TYPE_SORTED_SET, GeeSortedSet);
	gee_collection_add_all (G_TYPE_CHECK_INSTANCE_CAST (sorted, GEE_TYPE_COLLECTION, GeeCollection), emails);
	result = sorted;
	return result;
}

GearyEmailIdentifier*
geary_email_identifier_construct (GType object_type)
{
	GearyEmailIdentifier * self = NULL;
	self = (GearyEmailIdentifier*) geary_base_object_construct (object_type);
	return self;
}

static void
geary_email_identifier_class_init (GearyEmailIdentifierClass * klass,
                                   gpointer klass_data)
{
	geary_email_identifier_parent_class = g_type_class_peek_parent (klass);
	((GearyEmailIdentifierClass *) klass)->hash = (guint (*) (GearyEmailIdentifier*)) geary_email_identifier_real_hash;
	((GearyEmailIdentifierClass *) klass)->equal_to = (gboolean (*) (GearyEmailIdentifier*, GearyEmailIdentifier*)) geary_email_identifier_real_equal_to;
	((GearyEmailIdentifierClass *) klass)->to_variant = (GVariant* (*) (GearyEmailIdentifier*)) geary_email_identifier_real_to_variant;
	((GearyEmailIdentifierClass *) klass)->to_string = (gchar* (*) (GearyEmailIdentifier*)) geary_email_identifier_real_to_string;
	((GearyEmailIdentifierClass *) klass)->stable_sort_comparator = (gint (*) (GearyEmailIdentifier*, GearyEmailIdentifier*)) geary_email_identifier_real_stable_sort_comparator;
	((GearyEmailIdentifierClass *) klass)->natural_sort_comparator = (gint (*) (GearyEmailIdentifier*, GearyEmailIdentifier*)) geary_email_identifier_real_natural_sort_comparator;
}

static void
geary_email_identifier_gee_hashable_interface_init (GeeHashableIface * iface,
                                                    gpointer iface_data)
{
	geary_email_identifier_gee_hashable_parent_iface = g_type_interface_peek_parent (iface);
	iface->hash = (guint (*) (GeeHashable*)) geary_email_identifier_hash;
	iface->equal_to = (gboolean (*) (GeeHashable*, gconstpointer)) geary_email_identifier_equal_to;
}

static void
geary_email_identifier_instance_init (GearyEmailIdentifier * self,
                                      gpointer klass)
{
}

/**
 * A unique identifier for an {@link Email} throughout a Geary {@link Account}.
 *
 * Every Email has an {@link EmailIdentifier}.  Since the Geary engine supports the notion of an
 * Email being located in multiple {@link Folder}s, this identifier can be used to detect these
 * duplicates no matter how it's retrieved -- from any Folder or an Account object (i.e. via
 * search).
 *
 * TODO: EmailIdentifiers may be expanded in the future to include Account information, meaning
 * they will be unique throughout the Geary engine.
 */
 G_GNUC_NO_INLINE static GType
geary_email_identifier_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyEmailIdentifierClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_email_identifier_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyEmailIdentifier), 0, (GInstanceInitFunc) geary_email_identifier_instance_init, NULL };
	static const GInterfaceInfo gee_hashable_info = { (GInterfaceInitFunc) geary_email_identifier_gee_hashable_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType geary_email_identifier_type_id;
	geary_email_identifier_type_id = g_type_register_static (GEARY_TYPE_BASE_OBJECT, "GearyEmailIdentifier", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
	g_type_add_interface_static (geary_email_identifier_type_id, GEE_TYPE_HASHABLE, &gee_hashable_info);
	return geary_email_identifier_type_id;
}

GType
geary_email_identifier_get_type (void)
{
	static gsize geary_email_identifier_type_id__once = 0;
	if (g_once_init_enter (&geary_email_identifier_type_id__once)) {
		GType geary_email_identifier_type_id;
		geary_email_identifier_type_id = geary_email_identifier_get_type_once ();
		g_once_init_leave (&geary_email_identifier_type_id__once, geary_email_identifier_type_id);
	}
	return geary_email_identifier_type_id__once;
}

