/* GStreamer
 * Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/*
 * Unless otherwise indicated, Source Code is licensed under MIT license.
 * See further explanation attached in License Statement (distributed in the file
 * LICENSE).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * SECTION:gstrtspurl
 * @short_description: handling RTSP urls
 *  
 * Provides helper functions to handle RTSP urls.
 *  
 * Last reviewed on 2007-07-25 (0.10.14)
 */

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

#include "gstrtspurl.h"

G_DEFINE_BOXED_TYPE (GstRTSPUrl, gst_rtsp_url,
    (GBoxedCopyFunc) gst_rtsp_url_copy, (GBoxedFreeFunc) gst_rtsp_url_free);

static const struct
{
  const char scheme[6];
  GstRTSPLowerTrans transports;
} rtsp_schemes_map[] = {
  {
  "rtsp", GST_RTSP_LOWER_TRANS_TCP | GST_RTSP_LOWER_TRANS_UDP |
        GST_RTSP_LOWER_TRANS_UDP_MCAST}, {
  "rtspu", GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST}, {
  "rtspt", GST_RTSP_LOWER_TRANS_TCP}, {
  "rtsph", GST_RTSP_LOWER_TRANS_HTTP | GST_RTSP_LOWER_TRANS_TCP}, {
  "rtsps", GST_RTSP_LOWER_TRANS_TCP | GST_RTSP_LOWER_TRANS_UDP |
        GST_RTSP_LOWER_TRANS_UDP_MCAST | GST_RTSP_LOWER_TRANS_TLS}, {
  "rtspsu",
        GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST |
        GST_RTSP_LOWER_TRANS_TLS}, {
  "rtspst", GST_RTSP_LOWER_TRANS_TCP | GST_RTSP_LOWER_TRANS_TLS}, {
  "rtspsh",
        GST_RTSP_LOWER_TRANS_HTTP | GST_RTSP_LOWER_TRANS_TCP |
        GST_RTSP_LOWER_TRANS_TLS}
};

/* format is rtsp[u]://[user:passwd@]host[:port]/abspath[?query] where host
 * is a host name, an IPv4 dotted decimal address ("aaa.bbb.ccc.ddd") or an
 * [IPv6] address ("[aabb:ccdd:eeff:gghh::sstt]" note the brackets around the
 * address to allow the distinction between ':' as an IPv6 hexgroup separator
 * and as a host/port separator) */

/**
 * gst_rtsp_url_parse:
 * @urlstr: the url string to parse
 * @url: (out): location to hold the result.
 *
 * Parse the RTSP @urlstr into a newly allocated #GstRTSPUrl. Free after usage
 * with gst_rtsp_url_free().
 *
 * Returns: a #GstRTSPResult.
 */
GstRTSPResult
gst_rtsp_url_parse (const gchar * urlstr, GstRTSPUrl ** url)
{
  GstRTSPUrl *res;
  gchar *p, *delim, *at, *col;
  gchar *host_end = NULL;
  guint i;

  g_return_val_if_fail (urlstr != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL);

  res = g_new0 (GstRTSPUrl, 1);

  p = (gchar *) urlstr;

  col = strstr (p, "://");
  if (col == NULL)
    goto invalid;

  for (i = 0; i < G_N_ELEMENTS (rtsp_schemes_map); i++) {
    if (g_ascii_strncasecmp (rtsp_schemes_map[i].scheme, p, col - p) == 0) {
      res->transports = rtsp_schemes_map[i].transports;
      p = col + 3;
      break;
    }
  }

  if (res->transports == GST_RTSP_LOWER_TRANS_UNKNOWN)
    goto invalid;

  delim = strpbrk (p, "/?");
  at = strchr (p, '@');

  if (at && delim && at > delim)
    at = NULL;

  if (at) {
    col = strchr (p, ':');

    /* must have a ':' and it must be before the '@' */
    if (col == NULL || col > at)
      goto invalid;

    res->user = g_strndup (p, col - p);
    col++;
    res->passwd = g_strndup (col, at - col);

    /* move to host */
    p = at + 1;
  }

  if (*p == '[') {
    res->family = GST_RTSP_FAM_INET6;

    /* we have an IPv6 address in the URL, find the ending ] which must be
     * before any delimiter */
    host_end = strchr (++p, ']');
    if (!host_end || (delim && host_end >= delim))
      goto invalid;

    /* a port specifier must follow the address immediately */
    col = host_end[1] == ':' ? host_end + 1 : NULL;
  } else {
    res->family = GST_RTSP_FAM_INET;

    col = strchr (p, ':');

    /* we have a ':' and a delimiter but the ':' is after the delimiter, it's
     * not really part of the hostname */
    if (col && delim && col >= delim)
      col = NULL;

    host_end = col ? col : delim;
  }

  if (!host_end)
    res->host = g_strdup (p);
  else {
    res->host = g_strndup (p, host_end - p);

    if (col) {
      res->port = strtoul (col + 1, NULL, 10);
    } else {
      /* no port specified, set to 0. gst_rtsp_url_get_port() will return the
       * default port */
      res->port = 0;
    }
  }
  p = delim;

  if (p && *p == '/') {
    delim = strchr (p, '?');
    if (!delim)
      res->abspath = g_strdup (p);
    else
      res->abspath = g_strndup (p, delim - p);
    p = delim;
  } else {
    /* IQinVision IQeye 1080p fails if a path '/' is provided
     * and RTSP does not mandate that a non-zero-length path
     * must be used */
    res->abspath = g_strdup ("");
  }

  if (p && *p == '?')
    res->query = g_strdup (p + 1);

  *url = res;

  return GST_RTSP_OK;

  /* ERRORS */
invalid:
  {
    gst_rtsp_url_free (res);
    return GST_RTSP_EINVAL;
  }
}

/**
 * gst_rtsp_url_copy:
 * @url: a #GstRTSPUrl
 *
 * Make a copy of @url.
 *
 * Returns: a copy of @url. Free with gst_rtsp_url_free () after usage.
 */
GstRTSPUrl *
gst_rtsp_url_copy (const GstRTSPUrl * url)
{
  GstRTSPUrl *res;

  g_return_val_if_fail (url != NULL, NULL);

  res = g_new0 (GstRTSPUrl, 1);

  res->transports = url->transports;
  res->family = url->family;
  res->user = g_strdup (url->user);
  res->passwd = g_strdup (url->passwd);
  res->host = g_strdup (url->host);
  res->port = url->port;
  res->abspath = g_strdup (url->abspath);
  res->query = g_strdup (url->query);

  return res;
}

/**
 * gst_rtsp_url_free:
 * @url: a #GstRTSPUrl
 *
 * Free the memory used by @url.
 */
void
gst_rtsp_url_free (GstRTSPUrl * url)
{
  if (url == NULL)
    return;

  g_free (url->user);
  g_free (url->passwd);
  g_free (url->host);
  g_free (url->abspath);
  g_free (url->query);
  g_free (url);
}

/**
 * gst_rtsp_url_set_port:
 * @url: a #GstRTSPUrl
 * @port: the port
 *
 * Set the port number in @url to @port.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_url_set_port (GstRTSPUrl * url, guint16 port)
{
  g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL);

  url->port = port;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_url_get_port:
 * @url: a #GstRTSPUrl
 * @port: location to hold the port
 *
 * Get the port number of @url.
 *
 * Returns: #GST_RTSP_OK.
 */
GstRTSPResult
gst_rtsp_url_get_port (const GstRTSPUrl * url, guint16 * port)
{
  g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL);
  g_return_val_if_fail (port != NULL, GST_RTSP_EINVAL);

  /* if a port was specified, use that else use the default port. */
  if (url->port != 0)
    *port = url->port;
  else
    *port = GST_RTSP_DEFAULT_PORT;

  return GST_RTSP_OK;
}

/**
 * gst_rtsp_url_get_request_uri:
 * @url: a #GstRTSPUrl
 *
 * Get a newly allocated string describing the request URI for @url. 
 *
 * Returns: a string with the request URI. g_free() after usage.
 */
gchar *
gst_rtsp_url_get_request_uri (const GstRTSPUrl * url)
{
  gchar *uri;
  const gchar *pre_host;
  const gchar *post_host;
  const gchar *pre_query;
  const gchar *query;

  g_return_val_if_fail (url != NULL, NULL);

  pre_host = url->family == GST_RTSP_FAM_INET6 ? "[" : "";
  post_host = url->family == GST_RTSP_FAM_INET6 ? "]" : "";
  pre_query = url->query ? "?" : "";
  query = url->query ? url->query : "";

  if (url->port != 0) {
    uri = g_strdup_printf ("rtsp://%s%s%s:%u%s%s%s", pre_host, url->host,
        post_host, url->port, url->abspath, pre_query, query);
  } else {
    uri = g_strdup_printf ("rtsp://%s%s%s%s%s%s", pre_host, url->host,
        post_host, url->abspath, pre_query, query);
  }

  return uri;
}

static int
hex_to_int (gchar c)
{
  if (c >= '0' && c <= '9')
    return c - '0';
  else if (c >= 'a' && c <= 'f')
    return c - 'a' + 10;
  else if (c >= 'A' && c <= 'F')
    return c - 'A' + 10;
  else
    return -1;
}

static void
unescape_path_component (gchar * comp)
{
  guint len = strlen (comp);
  guint i;

  for (i = 0; i + 2 < len; i++)
    if (comp[i] == '%') {
      int a, b;

      a = hex_to_int (comp[i + 1]);
      b = hex_to_int (comp[i + 2]);

      /* The a||b check is to ensure that the byte is not '\0' */
      if (a >= 0 && b >= 0 && (a || b)) {
        comp[i] = (gchar) (a * 16 + b);
        memmove (comp + i + 1, comp + i + 3, len - i - 3);
        len -= 2;
        comp[len] = '\0';
      }
    }
}

/**
 * gst_rtsp_url_decode_path_components:
 * @url: a #GstRTSPUrl
 *
 * Splits the path of @url on '/' boundaries, decoding the resulting components,
 *
 * The decoding performed by this routine is "URI decoding", as defined in RFC
 * 3986, commonly known as percent-decoding. For example, a string "foo\%2fbar"
 * will decode to "foo/bar" -- the \%2f being replaced by the corresponding byte
 * with hex value 0x2f. Note that there is no guarantee that the resulting byte
 * sequence is valid in any given encoding. As a special case, \%00 is not
 * unescaped to NUL, as that would prematurely terminate the string.
 *
 * Also note that since paths usually start with a slash, the first component
 * will usually be the empty string.
 *
 * Returns: a string vector. g_strfreev() after usage.
 */
gchar **
gst_rtsp_url_decode_path_components (const GstRTSPUrl * url)
{
  gchar **ret;
  guint i;

  g_return_val_if_fail (url != NULL, NULL);
  g_return_val_if_fail (url->abspath != NULL, NULL);

  ret = g_strsplit (url->abspath, "/", -1);

  for (i = 0; ret[i]; i++)
    unescape_path_component (ret[i]);

  return ret;
}
