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

/*
 * Copyright 2017 Software Freedom Conservancy Inc.
 * Copyright 2018 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-client-43.0.h"
#include <goa/goa.h>
#include <gio/gio.h>
#include "geary-engine.h"
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>

enum  {
	GOA_MEDIATOR_0_PROPERTY,
	GOA_MEDIATOR_NUM_PROPERTIES
};
static GParamSpec* goa_mediator_properties[GOA_MEDIATOR_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _GoaMediatorUpdateData GoaMediatorUpdateData;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _GoaMediatorLoadTokenData GoaMediatorLoadTokenData;

struct _GoaMediatorPrivate {
	GoaObject* handle;
};

struct _GoaMediatorUpdateData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GoaMediator* self;
	GearyAccountInformation* geary_account;
	GCancellable* cancellable;
	GearyServiceInformation* _tmp0_;
	GearyServiceInformation* _tmp1_;
	GearyServiceInformation* _tmp2_;
	GearyServiceInformation* _tmp3_;
	GError* _inner_error0_;
};

struct _GoaMediatorLoadTokenData {
	int _state_;
	GObject* _source_object_;
	GAsyncResult* _res_;
	GTask* _async_result;
	GoaMediator* self;
	GearyAccountInformation* account;
	GearyServiceInformation* service;
	GCancellable* cancellable;
	gboolean result;
	GoaAccount* goa_account;
	GoaObject* _tmp0_;
	GoaAccount* _tmp1_;
	GoaAccount* _tmp2_;
	GError* err;
	GError* _tmp3_;
	const gchar* _tmp4_;
	GoaAccount* _tmp5_;
	gboolean loaded;
	gchar* token;
	GearyCredentialsMethod _tmp6_;
	GoaObject* _tmp7_;
	GoaOAuth2Based* _tmp8_;
	GoaOAuth2Based* _tmp9_;
	gchar* _tmp10_;
	GearyProtocol _tmp11_;
	GearyProtocol _tmp12_;
	GoaObject* _tmp13_;
	GoaPasswordBased* _tmp14_;
	GoaPasswordBased* _tmp15_;
	gchar* _tmp16_;
	GoaObject* _tmp17_;
	GoaPasswordBased* _tmp18_;
	GoaPasswordBased* _tmp19_;
	gchar* _tmp20_;
	const gchar* _tmp21_;
	GearyCredentials* _tmp22_;
	GearyCredentials* _tmp23_;
	const gchar* _tmp24_;
	GearyCredentials* _tmp25_;
	GearyCredentials* _tmp26_;
	GError* _inner_error0_;
};

static gint GoaMediator_private_offset;
static gpointer goa_mediator_parent_class = NULL;
static GearyCredentialsMediatorIface * goa_mediator_geary_credentials_mediator_parent_iface = NULL;

static void goa_mediator_update_data_free (gpointer _data);
static gboolean goa_mediator_update_co (GoaMediatorUpdateData* _data_);
static GearyCredentialsMethod goa_mediator_get_auth_method (GoaMediator* self,
                                                     GError** error);
static void goa_mediator_update_imap_config (GoaMediator* self,
                                      GearyServiceInformation* service,
                                      GError** error);
static void goa_mediator_update_smtp_config (GoaMediator* self,
                                      GearyServiceInformation* service,
                                      GError** error);
static void goa_mediator_real_load_token_data_free (gpointer _data);
static void goa_mediator_real_load_token (GoaMediator* self,
                                   GearyAccountInformation* account,
                                   GearyServiceInformation* service,
                                   GCancellable* cancellable,
                                   GAsyncReadyCallback _callback_,
                                   gpointer _user_data_);
static gboolean goa_mediator_real_load_token_co (GoaMediatorLoadTokenData* _data_);
static void goa_mediator_load_token_ready (GObject* source_object,
                                    GAsyncResult* _res_,
                                    gpointer _user_data_);
static void goa_mediator_parse_host_name (GoaMediator* self,
                                   GearyServiceInformation* service,
                                   const gchar* host_name);
static void goa_mediator_finalize (GObject * obj);
static GType goa_mediator_get_type_once (void);

static inline gpointer
goa_mediator_get_instance_private (GoaMediator* self)
{
	return G_STRUCT_MEMBER_P (self, GoaMediator_private_offset);
}

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

GoaMediator*
goa_mediator_construct (GType object_type,
                        GoaObject* handle)
{
	GoaMediator * self = NULL;
	GoaObject* _tmp0_;
	g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (handle, goa_object_get_type ()), NULL);
	self = (GoaMediator*) g_object_new (object_type, NULL);
	_tmp0_ = _g_object_ref0 (handle);
	_g_object_unref0 (self->priv->handle);
	self->priv->handle = _tmp0_;
	return self;
}

GoaMediator*
goa_mediator_new (GoaObject* handle)
{
	return goa_mediator_construct (TYPE_GOA_MEDIATOR, handle);
}

GearyServiceProvider
goa_mediator_get_service_provider (GoaMediator* self)
{
	GearyServiceProvider provider = 0;
	GoaObject* _tmp0_;
	GoaAccount* _tmp1_;
	GoaAccount* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	GQuark _tmp8_ = 0U;
	static GQuark _tmp7_label0 = 0;
	static GQuark _tmp7_label1 = 0;
	GearyServiceProvider result;
	g_return_val_if_fail (IS_GOA_MEDIATOR (self), 0);
	provider = GEARY_SERVICE_PROVIDER_OTHER;
	_tmp0_ = self->priv->handle;
	_tmp1_ = goa_object_get_account (_tmp0_);
	_tmp2_ = _tmp1_;
	g_object_get (_tmp2_, "provider-type", &_tmp3_, NULL);
	_tmp4_ = _tmp3_;
	_tmp5_ = _tmp4_;
	_g_object_unref0 (_tmp2_);
	_tmp6_ = _tmp5_;
	_tmp8_ = (NULL == _tmp6_) ? 0 : g_quark_from_string (_tmp6_);
	g_free (_tmp6_);
	if (_tmp8_ == ((0 != _tmp7_label0) ? _tmp7_label0 : (_tmp7_label0 = g_quark_from_static_string ("google")))) {
		switch (0) {
			default:
			{
				provider = GEARY_SERVICE_PROVIDER_GMAIL;
				break;
			}
		}
	} else if (_tmp8_ == ((0 != _tmp7_label1) ? _tmp7_label1 : (_tmp7_label1 = g_quark_from_static_string ("windows_live")))) {
		switch (0) {
			default:
			{
				provider = GEARY_SERVICE_PROVIDER_OUTLOOK;
				break;
			}
		}
	}
	result = provider;
	return result;
}

gchar*
goa_mediator_get_service_label (GoaMediator* self)
{
	GoaObject* _tmp0_;
	GoaAccount* _tmp1_;
	GoaAccount* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* result;
	g_return_val_if_fail (IS_GOA_MEDIATOR (self), NULL);
	_tmp0_ = self->priv->handle;
	_tmp1_ = goa_object_get_account (_tmp0_);
	_tmp2_ = _tmp1_;
	g_object_get (_tmp2_, "provider-name", &_tmp3_, NULL);
	_tmp4_ = _tmp3_;
	_tmp5_ = _tmp4_;
	_g_object_unref0 (_tmp2_);
	result = _tmp5_;
	return result;
}

static void
goa_mediator_update_data_free (gpointer _data)
{
	GoaMediatorUpdateData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->geary_account);
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->self);
	g_slice_free (GoaMediatorUpdateData, _data_);
}

void
goa_mediator_update (GoaMediator* self,
                     GearyAccountInformation* geary_account,
                     GCancellable* cancellable,
                     GAsyncReadyCallback _callback_,
                     gpointer _user_data_)
{
	GoaMediatorUpdateData* _data_;
	GoaMediator* _tmp0_;
	GearyAccountInformation* _tmp1_;
	GCancellable* _tmp2_;
	g_return_if_fail (IS_GOA_MEDIATOR (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (geary_account, GEARY_TYPE_ACCOUNT_INFORMATION));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GoaMediatorUpdateData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, goa_mediator_update_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (geary_account);
	_g_object_unref0 (_data_->geary_account);
	_data_->geary_account = _tmp1_;
	_tmp2_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp2_;
	goa_mediator_update_co (_data_);
}

void
goa_mediator_update_finish (GoaMediator* self,
                            GAsyncResult* _res_,
                            GError** error)
{
	GoaMediatorUpdateData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		return;
	}
}

static gboolean
goa_mediator_update_co (GoaMediatorUpdateData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	goa_mediator_get_auth_method (_data_->self, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp0_ = geary_account_information_get_incoming (_data_->geary_account);
	_data_->_tmp1_ = _data_->_tmp0_;
	goa_mediator_update_imap_config (_data_->self, _data_->_tmp1_, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	_data_->_tmp2_ = geary_account_information_get_outgoing (_data_->geary_account);
	_data_->_tmp3_ = _data_->_tmp2_;
	goa_mediator_update_smtp_config (_data_->self, _data_->_tmp3_, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

static void
goa_mediator_real_load_token_data_free (gpointer _data)
{
	GoaMediatorLoadTokenData* _data_;
	_data_ = _data;
	_g_object_unref0 (_data_->account);
	_g_object_unref0 (_data_->service);
	_g_object_unref0 (_data_->cancellable);
	_g_object_unref0 (_data_->self);
	g_slice_free (GoaMediatorLoadTokenData, _data_);
}

static void
goa_mediator_real_load_token (GoaMediator* self,
                              GearyAccountInformation* account,
                              GearyServiceInformation* service,
                              GCancellable* cancellable,
                              GAsyncReadyCallback _callback_,
                              gpointer _user_data_)
{
	GoaMediatorLoadTokenData* _data_;
	GoaMediator* _tmp0_;
	GearyAccountInformation* _tmp1_;
	GearyServiceInformation* _tmp2_;
	GCancellable* _tmp3_;
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (account, GEARY_TYPE_ACCOUNT_INFORMATION));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (service, GEARY_TYPE_SERVICE_INFORMATION));
	g_return_if_fail ((cancellable == NULL) || G_TYPE_CHECK_INSTANCE_TYPE (cancellable, g_cancellable_get_type ()));
	_data_ = g_slice_new0 (GoaMediatorLoadTokenData);
	_data_->_async_result = g_task_new (G_OBJECT (self), cancellable, _callback_, _user_data_);
	g_task_set_task_data (_data_->_async_result, _data_, goa_mediator_real_load_token_data_free);
	_tmp0_ = _g_object_ref0 (self);
	_data_->self = _tmp0_;
	_tmp1_ = _g_object_ref0 (account);
	_g_object_unref0 (_data_->account);
	_data_->account = _tmp1_;
	_tmp2_ = _g_object_ref0 (service);
	_g_object_unref0 (_data_->service);
	_data_->service = _tmp2_;
	_tmp3_ = _g_object_ref0 (cancellable);
	_g_object_unref0 (_data_->cancellable);
	_data_->cancellable = _tmp3_;
	goa_mediator_real_load_token_co (_data_);
}

static gboolean
goa_mediator_real_load_token_finish (GoaMediator* self,
                                     GAsyncResult* _res_,
                                     GError** error)
{
	gboolean result;
	GoaMediatorLoadTokenData* _data_;
	_data_ = g_task_propagate_pointer (G_TASK (_res_), error);
	if (NULL == _data_) {
		gboolean _tmp0_ = FALSE;
		return _tmp0_;
	}
	result = _data_->result;
	return result;
}

static void
goa_mediator_load_token_ready (GObject* source_object,
                               GAsyncResult* _res_,
                               gpointer _user_data_)
{
	GoaMediatorLoadTokenData* _data_;
	_data_ = _user_data_;
	_data_->_source_object_ = source_object;
	_data_->_res_ = _res_;
	goa_mediator_real_load_token_co (_data_);
}

static gboolean
goa_mediator_real_load_token_co (GoaMediatorLoadTokenData* _data_)
{
	switch (_data_->_state_) {
		case 0:
		goto _state_0;
		case 1:
		goto _state_1;
		case 2:
		goto _state_2;
		case 3:
		goto _state_3;
		case 4:
		goto _state_4;
		case 5:
		goto _state_5;
		default:
		g_assert_not_reached ();
	}
	_state_0:
	_data_->_tmp0_ = _data_->self->priv->handle;
	_data_->_tmp1_ = goa_object_get_account (_data_->_tmp0_);
	_data_->goa_account = _data_->_tmp1_;
	if (_data_->account != NULL) {
		{
			_data_->_tmp2_ = _data_->goa_account;
			_data_->_state_ = 1;
			goa_account_call_ensure_credentials (_data_->_tmp2_, _data_->cancellable, goa_mediator_load_token_ready, _data_);
			return FALSE;
			_state_1:
			goa_account_call_ensure_credentials_finish (_data_->_tmp2_, NULL, _data_->_res_, &_data_->_inner_error0_);
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				if (g_error_matches (_data_->_inner_error0_, GOA_ERROR, GOA_ERROR_NOT_AUTHORIZED)) {
					goto __catch0_goa_error_not_authorized;
				}
				goto __finally0;
			}
		}
		goto __finally0;
		__catch0_goa_error_not_authorized:
		{
			_data_->err = _data_->_inner_error0_;
			_data_->_inner_error0_ = NULL;
			_data_->_tmp3_ = _data_->err;
			_data_->_tmp4_ = _data_->_tmp3_->message;
			g_debug ("goa-mediator.vala:66: GOA updating auth failed, retrying: %s", _data_->_tmp4_);
			_data_->_tmp5_ = _data_->goa_account;
			_data_->_state_ = 2;
			goa_account_call_ensure_credentials (_data_->_tmp5_, _data_->cancellable, goa_mediator_load_token_ready, _data_);
			return FALSE;
			_state_2:
			goa_account_call_ensure_credentials_finish (_data_->_tmp5_, NULL, _data_->_res_, &_data_->_inner_error0_);
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				_g_error_free0 (_data_->err);
				goto __finally0;
			}
			_g_error_free0 (_data_->err);
		}
		__finally0:
		if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
			g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
			_g_object_unref0 (_data_->goa_account);
			g_object_unref (_data_->_async_result);
			return FALSE;
		}
	}
	_data_->loaded = FALSE;
	_data_->token = NULL;
	_data_->_tmp6_ = goa_mediator_get_auth_method (_data_->self, &_data_->_inner_error0_);
	if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
		g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
		_g_free0 (_data_->token);
		_g_object_unref0 (_data_->goa_account);
		g_object_unref (_data_->_async_result);
		return FALSE;
	}
	switch (_data_->_tmp6_) {
		case GEARY_CREDENTIALS_METHOD_OAUTH2:
		{
			_data_->_tmp7_ = _data_->self->priv->handle;
			_data_->_tmp8_ = goa_object_get_oauth2_based (_data_->_tmp7_);
			_data_->_tmp9_ = _data_->_tmp8_;
			_data_->_tmp10_ = NULL;
			_data_->_state_ = 3;
			goa_oauth2_based_call_get_access_token (_data_->_tmp9_, _data_->cancellable, goa_mediator_load_token_ready, _data_);
			return FALSE;
			_state_3:
			goa_oauth2_based_call_get_access_token_finish (_data_->_tmp9_, &_data_->_tmp10_, NULL, _data_->_res_, &_data_->_inner_error0_);
			_g_free0 (_data_->token);
			_data_->token = _data_->_tmp10_;
			_g_object_unref0 (_data_->_tmp9_);
			if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
				g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
				_g_free0 (_data_->token);
				_g_object_unref0 (_data_->goa_account);
				g_object_unref (_data_->_async_result);
				return FALSE;
			}
			break;
		}
		case GEARY_CREDENTIALS_METHOD_PASSWORD:
		{
			_data_->_tmp11_ = geary_service_information_get_protocol (_data_->service);
			_data_->_tmp12_ = _data_->_tmp11_;
			switch (_data_->_tmp12_) {
				case GEARY_PROTOCOL_IMAP:
				{
					_data_->_tmp13_ = _data_->self->priv->handle;
					_data_->_tmp14_ = goa_object_get_password_based (_data_->_tmp13_);
					_data_->_tmp15_ = _data_->_tmp14_;
					_data_->_tmp16_ = NULL;
					_data_->_state_ = 4;
					goa_password_based_call_get_password (_data_->_tmp15_, "imap-password", _data_->cancellable, goa_mediator_load_token_ready, _data_);
					return FALSE;
					_state_4:
					goa_password_based_call_get_password_finish (_data_->_tmp15_, &_data_->_tmp16_, _data_->_res_, &_data_->_inner_error0_);
					_g_free0 (_data_->token);
					_data_->token = _data_->_tmp16_;
					_g_object_unref0 (_data_->_tmp15_);
					if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
						g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
						_g_free0 (_data_->token);
						_g_object_unref0 (_data_->goa_account);
						g_object_unref (_data_->_async_result);
						return FALSE;
					}
					break;
				}
				case GEARY_PROTOCOL_SMTP:
				{
					_data_->_tmp17_ = _data_->self->priv->handle;
					_data_->_tmp18_ = goa_object_get_password_based (_data_->_tmp17_);
					_data_->_tmp19_ = _data_->_tmp18_;
					_data_->_tmp20_ = NULL;
					_data_->_state_ = 5;
					goa_password_based_call_get_password (_data_->_tmp19_, "smtp-password", _data_->cancellable, goa_mediator_load_token_ready, _data_);
					return FALSE;
					_state_5:
					goa_password_based_call_get_password_finish (_data_->_tmp19_, &_data_->_tmp20_, _data_->_res_, &_data_->_inner_error0_);
					_g_free0 (_data_->token);
					_data_->token = _data_->_tmp20_;
					_g_object_unref0 (_data_->_tmp19_);
					if (G_UNLIKELY (_data_->_inner_error0_ != NULL)) {
						g_task_return_error (_data_->_async_result, _data_->_inner_error0_);
						_g_free0 (_data_->token);
						_g_object_unref0 (_data_->goa_account);
						g_object_unref (_data_->_async_result);
						return FALSE;
					}
					break;
				}
				default:
				{
					_data_->result = FALSE;
					_g_free0 (_data_->token);
					_g_object_unref0 (_data_->goa_account);
					g_task_return_pointer (_data_->_async_result, _data_, NULL);
					if (_data_->_state_ != 0) {
						while (!g_task_get_completed (_data_->_async_result)) {
							g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
						}
					}
					g_object_unref (_data_->_async_result);
					return FALSE;
				}
			}
			break;
		}
		default:
		break;
	}
	_data_->_tmp21_ = _data_->token;
	if (_data_->_tmp21_ != NULL) {
		_data_->_tmp22_ = geary_service_information_get_credentials (_data_->service);
		_data_->_tmp23_ = _data_->_tmp22_;
		_data_->_tmp24_ = _data_->token;
		_data_->_tmp25_ = geary_credentials_copy_with_token (_data_->_tmp23_, _data_->_tmp24_);
		_data_->_tmp26_ = _data_->_tmp25_;
		geary_service_information_set_credentials (_data_->service, _data_->_tmp26_);
		_g_object_unref0 (_data_->_tmp26_);
		_data_->loaded = TRUE;
	}
	_data_->result = _data_->loaded;
	_g_free0 (_data_->token);
	_g_object_unref0 (_data_->goa_account);
	g_task_return_pointer (_data_->_async_result, _data_, NULL);
	if (_data_->_state_ != 0) {
		while (!g_task_get_completed (_data_->_async_result)) {
			g_main_context_iteration (g_task_get_context (_data_->_async_result), TRUE);
		}
	}
	g_object_unref (_data_->_async_result);
	return FALSE;
}

void
goa_mediator_load_token (GoaMediator* self,
                         GearyAccountInformation* account,
                         GearyServiceInformation* service,
                         GCancellable* cancellable,
                         GAsyncReadyCallback _callback_,
                         gpointer _user_data_)
{
	GoaMediatorClass* _klass_;
	_klass_ = GOA_MEDIATOR_GET_CLASS (self);
	if (_klass_->load_token) {
		_klass_->load_token (self, account, service, cancellable, _callback_, _user_data_);
	}
}

gboolean
goa_mediator_load_token_finish (GoaMediator* self,
                                GAsyncResult* _res_,
                                GError** error)
{
	GoaMediatorClass* _klass_;
	_klass_ = GOA_MEDIATOR_GET_CLASS (self);
	if (_klass_->load_token_finish) {
		return _klass_->load_token_finish (self, _res_, error);
	}
	return FALSE;
}

static GearyCredentialsMethod
goa_mediator_get_auth_method (GoaMediator* self,
                              GError** error)
{
	GoaObject* _tmp0_;
	GoaOAuth2Based* _tmp1_;
	GoaOAuth2Based* _tmp2_;
	gboolean _tmp3_;
	GoaObject* _tmp4_;
	GoaPasswordBased* _tmp5_;
	GoaPasswordBased* _tmp6_;
	gboolean _tmp7_;
	GError* _tmp8_;
	GError* _inner_error0_ = NULL;
	GearyCredentialsMethod result;
	g_return_val_if_fail (IS_GOA_MEDIATOR (self), 0);
	_tmp0_ = self->priv->handle;
	_tmp1_ = goa_object_get_oauth2_based (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = _tmp2_ != NULL;
	_g_object_unref0 (_tmp2_);
	if (_tmp3_) {
		result = GEARY_CREDENTIALS_METHOD_OAUTH2;
		return result;
	}
	_tmp4_ = self->priv->handle;
	_tmp5_ = goa_object_get_password_based (_tmp4_);
	_tmp6_ = _tmp5_;
	_tmp7_ = _tmp6_ != NULL;
	_g_object_unref0 (_tmp6_);
	if (_tmp7_) {
		result = GEARY_CREDENTIALS_METHOD_PASSWORD;
		return result;
	}
	_tmp8_ = g_error_new_literal (GEARY_ENGINE_ERROR, GEARY_ENGINE_ERROR_UNSUPPORTED, "GOA account supports neither password or OAuth2 auth");
	_inner_error0_ = _tmp8_;
	g_propagate_error (error, _inner_error0_);
	return 0;
}

static void
goa_mediator_update_imap_config (GoaMediator* self,
                                 GearyServiceInformation* service,
                                 GError** error)
{
	GoaMail* mail = NULL;
	GoaObject* _tmp0_;
	GoaMail* _tmp1_;
	GoaMail* _tmp2_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (IS_GOA_MEDIATOR (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (service, GEARY_TYPE_SERVICE_INFORMATION));
	_tmp0_ = self->priv->handle;
	_tmp1_ = goa_object_get_mail (_tmp0_);
	mail = _tmp1_;
	_tmp2_ = mail;
	if (_tmp2_ != NULL) {
		GoaMail* _tmp3_;
		gchar* _tmp4_;
		gchar* _tmp5_;
		gchar* _tmp6_;
		GoaMail* _tmp7_;
		gboolean _tmp8_;
		gboolean _tmp9_;
		GearyCredentialsMethod _tmp13_ = 0;
		GoaMail* _tmp14_;
		gchar* _tmp15_;
		gchar* _tmp16_;
		gchar* _tmp17_;
		GearyCredentials* _tmp18_;
		GearyCredentials* _tmp19_;
		guint16 _tmp20_;
		guint16 _tmp21_;
		_tmp3_ = mail;
		g_object_get (_tmp3_, "imap-host", &_tmp4_, NULL);
		_tmp5_ = _tmp4_;
		_tmp6_ = _tmp5_;
		goa_mediator_parse_host_name (self, service, _tmp6_);
		_g_free0 (_tmp6_);
		_tmp7_ = mail;
		g_object_get (_tmp7_, "imap-use-ssl", &_tmp8_, NULL);
		_tmp9_ = _tmp8_;
		if (_tmp9_) {
			geary_service_information_set_transport_security (service, GEARY_TLS_NEGOTIATION_METHOD_TRANSPORT);
		} else {
			GoaMail* _tmp10_;
			gboolean _tmp11_;
			gboolean _tmp12_;
			_tmp10_ = mail;
			g_object_get (_tmp10_, "imap-use-tls", &_tmp11_, NULL);
			_tmp12_ = _tmp11_;
			if (_tmp12_) {
				geary_service_information_set_transport_security (service, GEARY_TLS_NEGOTIATION_METHOD_START_TLS);
			} else {
				geary_service_information_set_transport_security (service, GEARY_TLS_NEGOTIATION_METHOD_NONE);
			}
		}
		_tmp13_ = goa_mediator_get_auth_method (self, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			g_propagate_error (error, _inner_error0_);
			_g_object_unref0 (mail);
			return;
		}
		_tmp14_ = mail;
		g_object_get (_tmp14_, "imap-user-name", &_tmp15_, NULL);
		_tmp16_ = _tmp15_;
		_tmp17_ = _tmp16_;
		_tmp18_ = geary_credentials_new (_tmp13_, _tmp17_, NULL);
		_tmp19_ = _tmp18_;
		geary_service_information_set_credentials (service, _tmp19_);
		_g_object_unref0 (_tmp19_);
		_g_free0 (_tmp17_);
		_tmp20_ = geary_service_information_get_port (service);
		_tmp21_ = _tmp20_;
		if (((gint) _tmp21_) == 0) {
			geary_service_information_set_port (service, geary_service_information_get_default_port (service));
		}
	}
	_g_object_unref0 (mail);
}

static void
goa_mediator_update_smtp_config (GoaMediator* self,
                                 GearyServiceInformation* service,
                                 GError** error)
{
	GoaMail* mail = NULL;
	GoaObject* _tmp0_;
	GoaMail* _tmp1_;
	GoaMail* _tmp2_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (IS_GOA_MEDIATOR (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (service, GEARY_TYPE_SERVICE_INFORMATION));
	_tmp0_ = self->priv->handle;
	_tmp1_ = goa_object_get_mail (_tmp0_);
	mail = _tmp1_;
	_tmp2_ = mail;
	if (_tmp2_ != NULL) {
		GoaMail* _tmp3_;
		gchar* _tmp4_;
		gchar* _tmp5_;
		gchar* _tmp6_;
		GoaMail* _tmp7_;
		gboolean _tmp8_;
		gboolean _tmp9_;
		GoaMail* _tmp13_;
		gboolean _tmp14_;
		gboolean _tmp15_;
		GoaMail* _tmp16_;
		gboolean _tmp17_;
		gboolean _tmp18_;
		guint16 _tmp26_;
		guint16 _tmp27_;
		_tmp3_ = mail;
		g_object_get (_tmp3_, "smtp-host", &_tmp4_, NULL);
		_tmp5_ = _tmp4_;
		_tmp6_ = _tmp5_;
		goa_mediator_parse_host_name (self, service, _tmp6_);
		_g_free0 (_tmp6_);
		_tmp7_ = mail;
		g_object_get (_tmp7_, "smtp-use-ssl", &_tmp8_, NULL);
		_tmp9_ = _tmp8_;
		if (_tmp9_) {
			geary_service_information_set_transport_security (service, GEARY_TLS_NEGOTIATION_METHOD_TRANSPORT);
		} else {
			GoaMail* _tmp10_;
			gboolean _tmp11_;
			gboolean _tmp12_;
			_tmp10_ = mail;
			g_object_get (_tmp10_, "smtp-use-tls", &_tmp11_, NULL);
			_tmp12_ = _tmp11_;
			if (_tmp12_) {
				geary_service_information_set_transport_security (service, GEARY_TLS_NEGOTIATION_METHOD_START_TLS);
			} else {
				geary_service_information_set_transport_security (service, GEARY_TLS_NEGOTIATION_METHOD_NONE);
			}
		}
		_tmp13_ = mail;
		g_object_get (_tmp13_, "smtp-use-auth", &_tmp14_, NULL);
		_tmp15_ = _tmp14_;
		if (_tmp15_) {
			geary_service_information_set_credentials_requirement (service, GEARY_CREDENTIALS_REQUIREMENT_CUSTOM);
		} else {
			geary_service_information_set_credentials_requirement (service, GEARY_CREDENTIALS_REQUIREMENT_NONE);
		}
		_tmp16_ = mail;
		g_object_get (_tmp16_, "smtp-use-auth", &_tmp17_, NULL);
		_tmp18_ = _tmp17_;
		if (_tmp18_) {
			GearyCredentialsMethod _tmp19_ = 0;
			GoaMail* _tmp20_;
			gchar* _tmp21_;
			gchar* _tmp22_;
			gchar* _tmp23_;
			GearyCredentials* _tmp24_;
			GearyCredentials* _tmp25_;
			_tmp19_ = goa_mediator_get_auth_method (self, &_inner_error0_);
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				g_propagate_error (error, _inner_error0_);
				_g_object_unref0 (mail);
				return;
			}
			_tmp20_ = mail;
			g_object_get (_tmp20_, "smtp-user-name", &_tmp21_, NULL);
			_tmp22_ = _tmp21_;
			_tmp23_ = _tmp22_;
			_tmp24_ = geary_credentials_new (_tmp19_, _tmp23_, NULL);
			_tmp25_ = _tmp24_;
			geary_service_information_set_credentials (service, _tmp25_);
			_g_object_unref0 (_tmp25_);
			_g_free0 (_tmp23_);
		}
		_tmp26_ = geary_service_information_get_port (service);
		_tmp27_ = _tmp26_;
		if (((gint) _tmp27_) == 0) {
			geary_service_information_set_port (service, geary_service_information_get_default_port (service));
		}
	}
	_g_object_unref0 (mail);
}

static void
goa_mediator_parse_host_name (GoaMediator* self,
                              GearyServiceInformation* service,
                              const gchar* host_name)
{
	GError* _inner_error0_ = NULL;
	g_return_if_fail (IS_GOA_MEDIATOR (self));
	g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (service, GEARY_TYPE_SERVICE_INFORMATION));
	g_return_if_fail (host_name != NULL);
	geary_service_information_set_host (service, host_name);
	geary_service_information_set_port (service, (guint16) 0);
	{
		GNetworkAddress* address = NULL;
		guint16 _tmp0_;
		guint16 _tmp1_;
		GNetworkAddress* _tmp2_;
		const gchar* _tmp3_;
		const gchar* _tmp4_;
		guint _tmp5_;
		guint _tmp6_;
		_tmp0_ = geary_service_information_get_port (service);
		_tmp1_ = _tmp0_;
		_tmp2_ = g_network_address_parse (host_name, _tmp1_, &_inner_error0_);
		address = _tmp2_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp3_ = g_network_address_get_hostname (address);
		_tmp4_ = _tmp3_;
		geary_service_information_set_host (service, _tmp4_);
		_tmp5_ = g_network_address_get_port (address);
		_tmp6_ = _tmp5_;
		geary_service_information_set_port (service, (guint16) _tmp6_);
		_g_object_unref0 (address);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* err = NULL;
		GoaObject* _tmp7_;
		GoaAccount* _tmp8_;
		GoaAccount* _tmp9_;
		gchar* _tmp10_;
		gchar* _tmp11_;
		gchar* _tmp12_;
		GearyProtocol _tmp13_;
		GearyProtocol _tmp14_;
		gchar* _tmp15_;
		gchar* _tmp16_;
		GError* _tmp17_;
		const gchar* _tmp18_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp7_ = self->priv->handle;
		_tmp8_ = goa_object_get_account (_tmp7_);
		_tmp9_ = _tmp8_;
		g_object_get (_tmp9_, "id", &_tmp10_, NULL);
		_tmp11_ = _tmp10_;
		_tmp12_ = _tmp11_;
		_tmp13_ = geary_service_information_get_protocol (service);
		_tmp14_ = _tmp13_;
		_tmp15_ = geary_protocol_to_value (_tmp14_);
		_tmp16_ = _tmp15_;
		_tmp17_ = err;
		_tmp18_ = _tmp17_->message;
		g_warning ("goa-mediator.vala:192: GOA account \"%s\" %s hostname \"%s\": %", _tmp12_, _tmp16_, host_name, _tmp18_);
		_g_free0 (_tmp16_);
		_g_free0 (_tmp12_);
		_g_object_unref0 (_tmp9_);
		_g_error_free0 (err);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
}

static void
goa_mediator_class_init (GoaMediatorClass * klass,
                         gpointer klass_data)
{
	goa_mediator_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GoaMediator_private_offset);
	((GoaMediatorClass *) klass)->load_token = (void (*) (GoaMediator*, GearyAccountInformation*, GearyServiceInformation*, GCancellable*, GAsyncReadyCallback, gpointer)) goa_mediator_real_load_token;
	((GoaMediatorClass *) klass)->load_token_finish = (gboolean (*) (GoaMediator*, GAsyncResult*, GError**)) goa_mediator_real_load_token_finish;
	G_OBJECT_CLASS (klass)->finalize = goa_mediator_finalize;
}

static void
goa_mediator_geary_credentials_mediator_interface_init (GearyCredentialsMediatorIface * iface,
                                                        gpointer iface_data)
{
	goa_mediator_geary_credentials_mediator_parent_iface = g_type_interface_peek_parent (iface);
	iface->load_token = (void (*) (GearyCredentialsMediator*, GearyAccountInformation*, GearyServiceInformation*, GCancellable*, GAsyncReadyCallback, gpointer)) goa_mediator_load_token;
	iface->load_token_finish = (gboolean (*) (GearyCredentialsMediator*, GAsyncResult*, GError**)) goa_mediator_load_token_finish;
}

static void
goa_mediator_instance_init (GoaMediator * self,
                            gpointer klass)
{
	self->priv = goa_mediator_get_instance_private (self);
}

static void
goa_mediator_finalize (GObject * obj)
{
	GoaMediator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_GOA_MEDIATOR, GoaMediator);
	_g_object_unref0 (self->priv->handle);
	G_OBJECT_CLASS (goa_mediator_parent_class)->finalize (obj);
}

/** GNOME Online Accounts token adapter. */
static GType
goa_mediator_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GoaMediatorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) goa_mediator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GoaMediator), 0, (GInstanceInitFunc) goa_mediator_instance_init, NULL };
	static const GInterfaceInfo geary_credentials_mediator_info = { (GInterfaceInitFunc) goa_mediator_geary_credentials_mediator_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType goa_mediator_type_id;
	goa_mediator_type_id = g_type_register_static (G_TYPE_OBJECT, "GoaMediator", &g_define_type_info, 0);
	g_type_add_interface_static (goa_mediator_type_id, GEARY_TYPE_CREDENTIALS_MEDIATOR, &geary_credentials_mediator_info);
	GoaMediator_private_offset = g_type_add_instance_private (goa_mediator_type_id, sizeof (GoaMediatorPrivate));
	return goa_mediator_type_id;
}

GType
goa_mediator_get_type (void)
{
	static volatile gsize goa_mediator_type_id__once = 0;
	if (g_once_init_enter (&goa_mediator_type_id__once)) {
		GType goa_mediator_type_id;
		goa_mediator_type_id = goa_mediator_get_type_once ();
		g_once_init_leave (&goa_mediator_type_id__once, goa_mediator_type_id);
	}
	return goa_mediator_type_id__once;
}

