/* imap-quirks.c generated by valac 0.56.3, the Vala compiler
 * generated from imap-quirks.vala, do not modify */

/*
 * Copyright © 2020 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>

enum  {
	GEARY_IMAP_QUIRKS_0_PROPERTY,
	GEARY_IMAP_QUIRKS_FETCH_HEADER_PART_NO_SPACE_PROPERTY,
	GEARY_IMAP_QUIRKS_FLAG_ATOM_EXCEPTIONS_PROPERTY,
	GEARY_IMAP_QUIRKS_MAX_PIPELINE_BATCH_SIZE_PROPERTY,
	GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_MAILBOX_NAME_PROPERTY,
	GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_HOST_NAME_PROPERTY,
	GEARY_IMAP_QUIRKS_NUM_PROPERTIES
};
static GParamSpec* geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))

struct _GearyImapQuirksPrivate {
	gboolean _fetch_header_part_no_space;
	gchar* _flag_atom_exceptions;
	guint _max_pipeline_batch_size;
	gchar* _empty_envelope_mailbox_name;
	gchar* _empty_envelope_host_name;
};

static gint GearyImapQuirks_private_offset;
static gpointer geary_imap_quirks_parent_class = NULL;

static void geary_imap_quirks_finalize (GObject * obj);
static GType geary_imap_quirks_get_type_once (void);
static void _vala_geary_imap_quirks_get_property (GObject * object,
                                           guint property_id,
                                           GValue * value,
                                           GParamSpec * pspec);
static void _vala_geary_imap_quirks_set_property (GObject * object,
                                           guint property_id,
                                           const GValue * value,
                                           GParamSpec * pspec);

static inline gpointer
geary_imap_quirks_get_instance_private (GearyImapQuirks* self)
{
	return G_STRUCT_MEMBER_P (self, GearyImapQuirks_private_offset);
}

gboolean
geary_imap_quirks_get_fetch_header_part_no_space (GearyImapQuirks* self)
{
	gboolean result;
	g_return_val_if_fail (GEARY_IMAP_IS_QUIRKS (self), FALSE);
	result = self->priv->_fetch_header_part_no_space;
	return result;
}

void
geary_imap_quirks_set_fetch_header_part_no_space (GearyImapQuirks* self,
                                                  gboolean value)
{
	gboolean old_value;
	g_return_if_fail (GEARY_IMAP_IS_QUIRKS (self));
	old_value = geary_imap_quirks_get_fetch_header_part_no_space (self);
	if (old_value != value) {
		self->priv->_fetch_header_part_no_space = value;
		g_object_notify_by_pspec ((GObject *) self, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_FETCH_HEADER_PART_NO_SPACE_PROPERTY]);
	}
}

const gchar*
geary_imap_quirks_get_flag_atom_exceptions (GearyImapQuirks* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (GEARY_IMAP_IS_QUIRKS (self), NULL);
	_tmp0_ = self->priv->_flag_atom_exceptions;
	result = _tmp0_;
	return result;
}

void
geary_imap_quirks_set_flag_atom_exceptions (GearyImapQuirks* self,
                                            const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (GEARY_IMAP_IS_QUIRKS (self));
	old_value = geary_imap_quirks_get_flag_atom_exceptions (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_flag_atom_exceptions);
		self->priv->_flag_atom_exceptions = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_FLAG_ATOM_EXCEPTIONS_PROPERTY]);
	}
}

guint
geary_imap_quirks_get_max_pipeline_batch_size (GearyImapQuirks* self)
{
	guint result;
	g_return_val_if_fail (GEARY_IMAP_IS_QUIRKS (self), 0U);
	result = self->priv->_max_pipeline_batch_size;
	return result;
}

void
geary_imap_quirks_set_max_pipeline_batch_size (GearyImapQuirks* self,
                                               guint value)
{
	guint old_value;
	g_return_if_fail (GEARY_IMAP_IS_QUIRKS (self));
	old_value = geary_imap_quirks_get_max_pipeline_batch_size (self);
	if (old_value != value) {
		self->priv->_max_pipeline_batch_size = value;
		g_object_notify_by_pspec ((GObject *) self, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_MAX_PIPELINE_BATCH_SIZE_PROPERTY]);
	}
}

const gchar*
geary_imap_quirks_get_empty_envelope_mailbox_name (GearyImapQuirks* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (GEARY_IMAP_IS_QUIRKS (self), NULL);
	_tmp0_ = self->priv->_empty_envelope_mailbox_name;
	result = _tmp0_;
	return result;
}

void
geary_imap_quirks_set_empty_envelope_mailbox_name (GearyImapQuirks* self,
                                                   const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (GEARY_IMAP_IS_QUIRKS (self));
	old_value = geary_imap_quirks_get_empty_envelope_mailbox_name (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_empty_envelope_mailbox_name);
		self->priv->_empty_envelope_mailbox_name = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_MAILBOX_NAME_PROPERTY]);
	}
}

const gchar*
geary_imap_quirks_get_empty_envelope_host_name (GearyImapQuirks* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (GEARY_IMAP_IS_QUIRKS (self), NULL);
	_tmp0_ = self->priv->_empty_envelope_host_name;
	result = _tmp0_;
	return result;
}

void
geary_imap_quirks_set_empty_envelope_host_name (GearyImapQuirks* self,
                                                const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (GEARY_IMAP_IS_QUIRKS (self));
	old_value = geary_imap_quirks_get_empty_envelope_host_name (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_empty_envelope_host_name);
		self->priv->_empty_envelope_host_name = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_HOST_NAME_PROPERTY]);
	}
}

void
geary_imap_quirks_update_for_server (GearyImapQuirks* self,
                                     GearyImapClientSession* session)
{
	GearyImapStatusResponse* _tmp0_;
	GearyImapStatusResponse* _tmp1_;
	g_return_if_fail (GEARY_IMAP_IS_QUIRKS (self));
	g_return_if_fail (GEARY_IMAP_IS_CLIENT_SESSION (session));
	_tmp0_ = geary_imap_client_session_get_server_greeting (session);
	_tmp1_ = _tmp0_;
	if (_tmp1_ != NULL) {
		gchar* _tmp2_ = NULL;
		GearyImapStatusResponse* _tmp3_;
		GearyImapStatusResponse* _tmp4_;
		gchar* _tmp5_;
		gchar* greeting = NULL;
		gchar* _tmp7_;
		const gchar* _tmp8_;
		_tmp3_ = geary_imap_client_session_get_server_greeting (session);
		_tmp4_ = _tmp3_;
		_tmp5_ = geary_imap_status_response_get_text (_tmp4_);
		_tmp2_ = _tmp5_;
		if (_tmp2_ == NULL) {
			gchar* _tmp6_;
			_tmp6_ = g_strdup ("");
			_g_free0 (_tmp2_);
			_tmp2_ = _tmp6_;
		}
		_tmp7_ = _tmp2_;
		_tmp2_ = NULL;
		greeting = _tmp7_;
		_tmp8_ = greeting;
		if (g_str_has_prefix (_tmp8_, "Gimap")) {
			geary_imap_quirks_update_for_gmail (self);
		} else {
			const gchar* _tmp9_;
			_tmp9_ = greeting;
			if (g_str_has_prefix (_tmp9_, "The Microsoft Exchange")) {
				geary_imap_quirks_update_for_outlook (self);
			} else {
				const gchar* _tmp10_;
				_tmp10_ = greeting;
				if (g_str_has_prefix (_tmp10_, "Dovecot")) {
					geary_imap_quirks_update_for_dovecot (self);
				}
			}
		}
		_g_free0 (greeting);
		_g_free0 (_tmp2_);
	}
}

/**
     * Updates this quirks object with known quirks for GMail.
     *
     * As of 2020-05-02, GMail doesn't seem to quote flag
     * atoms containing reserved characters, and at least one
     * use of both `]` and ` ` have been found. This works
     * around the former.
     *
     * See [[https://gitlab.gnome.org/GNOME/geary/-/issues/746]]
     */
void
geary_imap_quirks_update_for_gmail (GearyImapQuirks* self)
{
	g_return_if_fail (GEARY_IMAP_IS_QUIRKS (self));
	geary_imap_quirks_set_flag_atom_exceptions (self, "]");
}

/**
     * Updates this quirks object with known quirks for Outlook.com.
     *
     * As of June 2016, outlook.com's IMAP servers have a bug where a
     * large number (~50) of pipelined STATUS commands on mailboxes
     * with many messages will eventually cause it to break command
     * parsing and return a BAD response, causing us to drop the
     * connection. Limit the number of pipelined commands per batch to
     * work around this.
     *
     * See [[https://bugzilla.gnome.org/show_bug.cgi?id=766552]]
     */
void
geary_imap_quirks_update_for_outlook (GearyImapQuirks* self)
{
	g_return_if_fail (GEARY_IMAP_IS_QUIRKS (self));
	geary_imap_quirks_set_max_pipeline_batch_size (self, (guint) 25);
}

/**
     * Updates this quirks object with known quirks for Dovecot
     *
     * Dovecot 2.3.4.1 and earlier uses "MISSING_MAILBOX" and
     * "MISSING_DOMAIN" in the address structures of FETCH ENVELOPE
     * replies when the mailbox or domain is missing.
     *
     * See [[https://dovecot.org/pipermail/dovecot/2020-August/119658.html]]
     */
void
geary_imap_quirks_update_for_dovecot (GearyImapQuirks* self)
{
	g_return_if_fail (GEARY_IMAP_IS_QUIRKS (self));
	geary_imap_quirks_set_empty_envelope_mailbox_name (self, "MISSING_MAILBOX");
	geary_imap_quirks_set_empty_envelope_host_name (self, "MISSING_DOMAIN");
}

GearyImapQuirks*
geary_imap_quirks_construct (GType object_type)
{
	GearyImapQuirks * self = NULL;
	self = (GearyImapQuirks*) geary_base_object_construct (object_type);
	return self;
}

GearyImapQuirks*
geary_imap_quirks_new (void)
{
	return geary_imap_quirks_construct (GEARY_IMAP_TYPE_QUIRKS);
}

static void
geary_imap_quirks_class_init (GearyImapQuirksClass * klass,
                              gpointer klass_data)
{
	geary_imap_quirks_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GearyImapQuirks_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_geary_imap_quirks_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_geary_imap_quirks_set_property;
	G_OBJECT_CLASS (klass)->finalize = geary_imap_quirks_finalize;
	/**
	     * Whether spaces are disallowed in header parts of fetch commands.
	     *
	     * If true, HEADER parts of a BODY section may not contain any
	     * spaces.
	     *
	     * E.g. this conformant form is not supported:
	     *
	     *     a008 UID FETCH * BODY.PEEK[HEADER.FIELDS (REFERENCES)]
	     *
	     * Whereas this non-conformant form is supported:
	     *
	     *     a008 UID FETCH * BODY.PEEK[HEADER.FIELDS(REFERENCES)]
	     */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_QUIRKS_FETCH_HEADER_PART_NO_SPACE_PROPERTY, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_FETCH_HEADER_PART_NO_SPACE_PROPERTY] = g_param_spec_boolean ("fetch-header-part-no-space", "fetch-header-part-no-space", "fetch-header-part-no-space", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	/** The set of additional characters allowed in an IMAP flag. */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_QUIRKS_FLAG_ATOM_EXCEPTIONS_PROPERTY, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_FLAG_ATOM_EXCEPTIONS_PROPERTY] = g_param_spec_string ("flag-atom-exceptions", "flag-atom-exceptions", "flag-atom-exceptions", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	/**
	     * The maximum number of commands that will be pipelined at once.
	     *
	     * If 0 (the default), there is no limit on the number of
	     * pipelined commands sent to this endpoint.
	     */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_QUIRKS_MAX_PIPELINE_BATCH_SIZE_PROPERTY, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_MAX_PIPELINE_BATCH_SIZE_PROPERTY] = g_param_spec_uint ("max-pipeline-batch-size", "max-pipeline-batch-size", "max-pipeline-batch-size", 0, G_MAXUINT, (guint) 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	/**
	     * The value sent by the server for missing envelope mailbox local parts.
	     *
	     * IMAP FETCH ENVELOPE structures use NIL for the "mailbox name"
	     * part (in addition to a NIL "host name" part) as an end-of-list
	     * marker for RFC822 group syntax. To indicate a missing
	     * local-part in a non-group mailbox some mail servers use a
	     * string such as "MISSING_MAILBOX" rather than the empty string.
	     */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_MAILBOX_NAME_PROPERTY, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_MAILBOX_NAME_PROPERTY] = g_param_spec_string ("empty-envelope-mailbox-name", "empty-envelope-mailbox-name", "empty-envelope-mailbox-name", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	/**
	     * The value sent by the server for missing envelope mailbox domains.
	     *
	     * IMAP FETCH ENVELOPE structures use NIL for the "host name"
	     * argument to indicate RFC822 group syntax. To indicate a missing
	     * some mail servers use a string such as "MISSING_DOMAIN" rather
	     * than the empty string.
	     */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_HOST_NAME_PROPERTY, geary_imap_quirks_properties[GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_HOST_NAME_PROPERTY] = g_param_spec_string ("empty-envelope-host-name", "empty-envelope-host-name", "empty-envelope-host-name", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
}

static void
geary_imap_quirks_instance_init (GearyImapQuirks * self,
                                 gpointer klass)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	self->priv = geary_imap_quirks_get_instance_private (self);
	self->priv->_fetch_header_part_no_space = FALSE;
	self->priv->_max_pipeline_batch_size = (guint) 0;
	_tmp0_ = g_strdup ("");
	self->priv->_empty_envelope_mailbox_name = _tmp0_;
	_tmp1_ = g_strdup ("");
	self->priv->_empty_envelope_host_name = _tmp1_;
}

static void
geary_imap_quirks_finalize (GObject * obj)
{
	GearyImapQuirks * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GEARY_IMAP_TYPE_QUIRKS, GearyImapQuirks);
	_g_free0 (self->priv->_flag_atom_exceptions);
	_g_free0 (self->priv->_empty_envelope_mailbox_name);
	_g_free0 (self->priv->_empty_envelope_host_name);
	G_OBJECT_CLASS (geary_imap_quirks_parent_class)->finalize (obj);
}

/**
 * A set of quirks for a specific IMAP service.
 */
 G_GNUC_NO_INLINE static GType
geary_imap_quirks_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GearyImapQuirksClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) geary_imap_quirks_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GearyImapQuirks), 0, (GInstanceInitFunc) geary_imap_quirks_instance_init, NULL };
	GType geary_imap_quirks_type_id;
	geary_imap_quirks_type_id = g_type_register_static (GEARY_TYPE_BASE_OBJECT, "GearyImapQuirks", &g_define_type_info, 0);
	GearyImapQuirks_private_offset = g_type_add_instance_private (geary_imap_quirks_type_id, sizeof (GearyImapQuirksPrivate));
	return geary_imap_quirks_type_id;
}

GType
geary_imap_quirks_get_type (void)
{
	static gsize geary_imap_quirks_type_id__once = 0;
	if (g_once_init_enter (&geary_imap_quirks_type_id__once)) {
		GType geary_imap_quirks_type_id;
		geary_imap_quirks_type_id = geary_imap_quirks_get_type_once ();
		g_once_init_leave (&geary_imap_quirks_type_id__once, geary_imap_quirks_type_id);
	}
	return geary_imap_quirks_type_id__once;
}

static void
_vala_geary_imap_quirks_get_property (GObject * object,
                                      guint property_id,
                                      GValue * value,
                                      GParamSpec * pspec)
{
	GearyImapQuirks * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_IMAP_TYPE_QUIRKS, GearyImapQuirks);
	switch (property_id) {
		case GEARY_IMAP_QUIRKS_FETCH_HEADER_PART_NO_SPACE_PROPERTY:
		g_value_set_boolean (value, geary_imap_quirks_get_fetch_header_part_no_space (self));
		break;
		case GEARY_IMAP_QUIRKS_FLAG_ATOM_EXCEPTIONS_PROPERTY:
		g_value_set_string (value, geary_imap_quirks_get_flag_atom_exceptions (self));
		break;
		case GEARY_IMAP_QUIRKS_MAX_PIPELINE_BATCH_SIZE_PROPERTY:
		g_value_set_uint (value, geary_imap_quirks_get_max_pipeline_batch_size (self));
		break;
		case GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_MAILBOX_NAME_PROPERTY:
		g_value_set_string (value, geary_imap_quirks_get_empty_envelope_mailbox_name (self));
		break;
		case GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_HOST_NAME_PROPERTY:
		g_value_set_string (value, geary_imap_quirks_get_empty_envelope_host_name (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_geary_imap_quirks_set_property (GObject * object,
                                      guint property_id,
                                      const GValue * value,
                                      GParamSpec * pspec)
{
	GearyImapQuirks * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GEARY_IMAP_TYPE_QUIRKS, GearyImapQuirks);
	switch (property_id) {
		case GEARY_IMAP_QUIRKS_FETCH_HEADER_PART_NO_SPACE_PROPERTY:
		geary_imap_quirks_set_fetch_header_part_no_space (self, g_value_get_boolean (value));
		break;
		case GEARY_IMAP_QUIRKS_FLAG_ATOM_EXCEPTIONS_PROPERTY:
		geary_imap_quirks_set_flag_atom_exceptions (self, g_value_get_string (value));
		break;
		case GEARY_IMAP_QUIRKS_MAX_PIPELINE_BATCH_SIZE_PROPERTY:
		geary_imap_quirks_set_max_pipeline_batch_size (self, g_value_get_uint (value));
		break;
		case GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_MAILBOX_NAME_PROPERTY:
		geary_imap_quirks_set_empty_envelope_mailbox_name (self, g_value_get_string (value));
		break;
		case GEARY_IMAP_QUIRKS_EMPTY_ENVELOPE_HOST_NAME_PROPERTY:
		geary_imap_quirks_set_empty_envelope_host_name (self, g_value_get_string (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

