/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */

/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2008 Red Hat, Inc.
 *
 * 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 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 "config.h"
#include <glib.h>
#include "glibintl.h"

#include "gsrvtarget.h"

#include <stdlib.h>
#include <string.h>


/**
 * SECTION:gsrvtarget
 * @short_description: DNS SRV record target
 * @include: gio/gio.h
 *
 * SRV (service) records are used by some network protocols to provide
 * service-specific aliasing and load-balancing. For example, XMPP
 * (Jabber) uses SRV records to locate the XMPP server for a domain;
 * rather than connecting directly to "example.com" or assuming a
 * specific server hostname like "xmpp.example.com", an XMPP client
 * would look up the "xmpp-client" SRV record for "example.com", and
 * then connect to whatever host was pointed to by that record.
 *
 * You can use g_resolver_lookup_service() or
 * g_resolver_lookup_service_async() to find the #GSrvTargets
 * for a given service. However, if you are simply planning to connect
 * to the remote service, you can use #GNetworkService's
 * #GSocketConnectable interface and not need to worry about
 * #GSrvTarget at all.
 */

struct _GSrvTarget {
  gchar   *hostname;
  guint16  port;

  guint16  priority;
  guint16  weight;
};

/**
 * GSrvTarget:
 *
 * A single target host/port that a network service is running on.
 */

G_DEFINE_BOXED_TYPE (GSrvTarget, g_srv_target,
                     g_srv_target_copy, g_srv_target_free)

/**
 * g_srv_target_new:
 * @hostname: the host that the service is running on
 * @port: the port that the service is running on
 * @priority: the target's priority
 * @weight: the target's weight
 *
 * Creates a new #GSrvTarget with the given parameters.
 *
 * You should not need to use this; normally #GSrvTargets are
 * created by #GResolver.
 *
 * Returns: a new #GSrvTarget.
 *
 * Since: 2.22
 */
GSrvTarget *
g_srv_target_new (const gchar *hostname,
                  guint16      port,
                  guint16      priority,
                  guint16      weight)
{
  GSrvTarget *target = g_slice_new0 (GSrvTarget);

  target->hostname = g_strdup (hostname);
  target->port = port;
  target->priority = priority;
  target->weight = weight;

  return target;
}

/**
 * g_srv_target_copy:
 * @target: a #GSrvTarget
 *
 * Copies @target
 *
 * Returns: a copy of @target
 *
 * Since: 2.22
 */
GSrvTarget *
g_srv_target_copy (GSrvTarget *target)
{
  return g_srv_target_new (target->hostname, target->port,
                           target->priority, target->weight);
}

/**
 * g_srv_target_free:
 * @target: a #GSrvTarget
 *
 * Frees @target
 *
 * Since: 2.22
 */
void
g_srv_target_free (GSrvTarget *target)
{
  g_free (target->hostname);
  g_slice_free (GSrvTarget, target);
}

/**
 * g_srv_target_get_hostname:
 * @target: a #GSrvTarget
 *
 * Gets @target's hostname (in ASCII form; if you are going to present
 * this to the user, you should use g_hostname_is_ascii_encoded() to
 * check if it contains encoded Unicode segments, and use
 * g_hostname_to_unicode() to convert it if it does.)
 *
 * Returns: @target's hostname
 *
 * Since: 2.22
 */
const gchar *
g_srv_target_get_hostname (GSrvTarget *target)
{
  return target->hostname;
}

/**
 * g_srv_target_get_port:
 * @target: a #GSrvTarget
 *
 * Gets @target's port
 *
 * Returns: @target's port
 *
 * Since: 2.22
 */
guint16
g_srv_target_get_port (GSrvTarget *target)
{
  return target->port;
}

/**
 * g_srv_target_get_priority:
 * @target: a #GSrvTarget
 *
 * Gets @target's priority. You should not need to look at this;
 * #GResolver already sorts the targets according to the algorithm in
 * RFC 2782.
 *
 * Returns: @target's priority
 *
 * Since: 2.22
 */
guint16
g_srv_target_get_priority (GSrvTarget *target)
{
  return target->priority;
}

/**
 * g_srv_target_get_weight:
 * @target: a #GSrvTarget
 *
 * Gets @target's weight. You should not need to look at this;
 * #GResolver already sorts the targets according to the algorithm in
 * RFC 2782.
 *
 * Returns: @target's weight
 *
 * Since: 2.22
 */
guint16
g_srv_target_get_weight (GSrvTarget *target)
{
  return target->weight;
}

static gint
compare_target (gconstpointer a, gconstpointer b)
{
  GSrvTarget *ta = (GSrvTarget *)a;
  GSrvTarget *tb = (GSrvTarget *)b;

  if (ta->priority == tb->priority)
    {
      /* Arrange targets of the same priority "in any order, except
       * that all those with weight 0 are placed at the beginning of
       * the list"
       */
      return ta->weight - tb->weight;
    }
  else
    return ta->priority - tb->priority;
}

/**
 * g_srv_target_list_sort: (skip)
 * @targets: a #GList of #GSrvTarget
 *
 * Sorts @targets in place according to the algorithm in RFC 2782.
 *
 * Returns: (transfer full): the head of the sorted list.
 *
 * Since: 2.22
 */
GList *
g_srv_target_list_sort (GList *targets)
{
  gint sum, num, val, priority, weight;
  GList *t, *out, *tail;
  GSrvTarget *target;

  if (!targets)
    return NULL;

  if (!targets->next)
    {
      target = targets->data;
      if (!strcmp (target->hostname, "."))
        {
          /* 'A Target of "." means that the service is decidedly not
           * available at this domain.'
           */
          g_srv_target_free (target);
          g_list_free (targets);
          return NULL;
        }
    }

  /* Sort input list by priority, and put the 0-weight targets first
   * in each priority group. Initialize output list to %NULL.
   */
  targets = g_list_sort (targets, compare_target);
  out = tail = NULL;

  /* For each group of targets with the same priority, remove them
   * from @targets and append them to @out in a valid order.
   */
  while (targets)
    {
      priority = ((GSrvTarget *)targets->data)->priority;

      /* Count the number of targets at this priority level, and
       * compute the sum of their weights.
       */
      sum = num = 0;
      for (t = targets; t; t = t->next)
        {
          target = (GSrvTarget *)t->data;
          if (target->priority != priority)
            break;
          sum += target->weight;
          num++;
        }

      /* While there are still targets at this priority level... */
      while (num)
        {
          /* Randomly select from the targets at this priority level,
           * giving precedence to the ones with higher weight,
           * according to the rules from RFC 2782.
           */
          val = g_random_int_range (0, sum + 1);
          for (t = targets; ; t = t->next)
            {
              weight = ((GSrvTarget *)t->data)->weight;
              if (weight >= val)
                break;
              val -= weight;
            }

          targets = g_list_remove_link (targets, t);

          if (!out)
            out = t;
          else
            tail->next = t;
          tail = t;

          sum -= weight;
          num--;
        }
    }

  return out;
}
