/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2018 Igalia S.L.
 *
 * 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/>.
 */

#include "mock-resolver.h"

struct _MockResolver
{
  GResolver parent_instance;
  guint ipv4_delay_ms;
  guint ipv6_delay_ms;
  GList *ipv4_results;
  GList *ipv6_results;
  GError *ipv4_error;
  GError *ipv6_error;
};

G_DEFINE_TYPE (MockResolver, mock_resolver, G_TYPE_RESOLVER)

MockResolver *
mock_resolver_new (void)
{
  return g_object_new (MOCK_TYPE_RESOLVER, NULL);
}

void
mock_resolver_set_ipv4_delay_ms (MockResolver *self, guint delay_ms)
{
  self->ipv4_delay_ms = delay_ms;
}

static gpointer
copy_object (gconstpointer obj, gpointer user_data)
{
  return g_object_ref (G_OBJECT (obj));
}

void
mock_resolver_set_ipv4_results (MockResolver *self, GList *results)
{
  if (self->ipv4_results)
    g_list_free_full (self->ipv4_results, g_object_unref);
  self->ipv4_results = g_list_copy_deep (results, copy_object, NULL);
}

void
mock_resolver_set_ipv4_error (MockResolver *self, GError *error)
{
  g_clear_error (&self->ipv4_error);
  if (error)
    self->ipv4_error = g_error_copy (error);
}

void
mock_resolver_set_ipv6_delay_ms (MockResolver *self, guint delay_ms)
{
  self->ipv6_delay_ms = delay_ms;
}

void
mock_resolver_set_ipv6_results (MockResolver *self, GList *results)
{
  if (self->ipv6_results)
    g_list_free_full (self->ipv6_results, g_object_unref);
  self->ipv6_results = g_list_copy_deep (results, copy_object, NULL);
}

void
mock_resolver_set_ipv6_error (MockResolver *self, GError *error)
{
  g_clear_error (&self->ipv6_error);
  if (error)
    self->ipv6_error = g_error_copy (error);
}

static void
do_lookup_by_name (GTask         *task,
                   gpointer       source_object,
                   gpointer       task_data,
                   GCancellable  *cancellable)
{
  MockResolver *self = source_object;
  GResolverNameLookupFlags flags = GPOINTER_TO_UINT(task_data);

  if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY)
    {
      g_usleep (self->ipv4_delay_ms * 1000);
      if (self->ipv4_error)
        g_task_return_error (task, g_error_copy (self->ipv4_error));
      else
        g_task_return_pointer (task, g_list_copy_deep (self->ipv4_results, copy_object, NULL), NULL);
    }
  else if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY)
    {
      g_usleep (self->ipv6_delay_ms * 1000);
      if (self->ipv6_error)
        g_task_return_error (task, g_error_copy (self->ipv6_error));
      else
        g_task_return_pointer (task, g_list_copy_deep (self->ipv6_results, copy_object, NULL), NULL);
    }
  else if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
    {
      /* This is only the minimal implementation needed for some tests */
      g_assert (self->ipv4_error == NULL && self->ipv6_error == NULL && self->ipv6_results == NULL);
      g_task_return_pointer (task, g_list_copy_deep (self->ipv4_results, copy_object, NULL), NULL);
    }
  else
    g_assert_not_reached ();
}

static void
lookup_by_name_with_flags_async (GResolver                *resolver,
                                 const gchar              *hostname,
                                 GResolverNameLookupFlags  flags,
                                 GCancellable             *cancellable,
                                 GAsyncReadyCallback       callback,
                                 gpointer                  user_data)
{
  GTask *task = g_task_new (resolver, cancellable, callback, user_data);
  g_task_set_task_data (task, GUINT_TO_POINTER(flags), NULL);
  g_task_run_in_thread (task, do_lookup_by_name);
  g_object_unref (task);
}

static GList *
lookup_by_name (GResolver    *resolver,
                const gchar  *hostname,
                GCancellable *cancellable,
                GError       **error)
{
  GList *result = NULL;
  GTask *task = g_task_new (resolver, cancellable, NULL, NULL);
  g_task_set_task_data (task, GUINT_TO_POINTER (G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT), NULL);
  g_task_run_in_thread_sync (task, do_lookup_by_name);
  result = g_task_propagate_pointer (task, error);
  g_object_unref (task);
  return result;
}


static GList *
lookup_by_name_with_flags_finish (GResolver     *resolver,
                                  GAsyncResult  *result,
                                  GError       **error)
{
  return g_task_propagate_pointer (G_TASK (result), error);
}

static void
mock_resolver_finalize (GObject *object)
{
  MockResolver *self = (MockResolver*)object;

  g_clear_error (&self->ipv4_error);
  g_clear_error (&self->ipv6_error);
  if (self->ipv6_results)
    g_list_free_full (self->ipv6_results, g_object_unref);
  if (self->ipv4_results)
    g_list_free_full (self->ipv4_results, g_object_unref);

  G_OBJECT_CLASS (mock_resolver_parent_class)->finalize (object);
}

static void
mock_resolver_class_init (MockResolverClass *klass)
{
  GResolverClass *resolver_class = G_RESOLVER_CLASS (klass);
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  resolver_class->lookup_by_name_with_flags_async  = lookup_by_name_with_flags_async;
  resolver_class->lookup_by_name_with_flags_finish = lookup_by_name_with_flags_finish;
  resolver_class->lookup_by_name = lookup_by_name;
  object_class->finalize = mock_resolver_finalize;
}

static void
mock_resolver_init (MockResolver *self)
{
}
