/*
 * parsechannels.c - 
 * Copyright (C) 2008 Zaheer Abbas Merali
 * 
 * Authors:
 *   Zaheer Abbas Merali <zaheerabbas at merali dot org>
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gst/gst.h>

#include <gst/gst-i18n-plugin.h>

#include "parsechannels.h"

#include <linux/dvb/frontend.h>

GST_DEBUG_CATEGORY_EXTERN (dvb_base_bin_debug);
#define GST_CAT_DEFAULT dvb_base_bin_debug

typedef enum
{
  CHANNEL_CONF_FORMAT_NONE,
  CHANNEL_CONF_FORMAT_DVBV5,
  CHANNEL_CONF_FORMAT_ZAP
} GstDvbChannelConfFormat;

typedef gboolean (*GstDvbV5ChannelsConfPropSetFunction) (GstElement *
    dvbbasebin, const gchar * property, GKeyFile * kf,
    const gchar * channel_name, const gchar * key);

typedef struct
{
  const gchar *conf_property;
  const gchar *elem_property;
  GstDvbV5ChannelsConfPropSetFunction set_func;
} GstDvbV5ChannelsConfToPropertyMap;

static gboolean parse_and_configure_from_v5_conf_file (GstElement * dvbbasebin,
    const gchar * filename, const gchar * channel_name, GError ** error);
static gboolean parse_and_configure_from_zap_conf_file (GstElement * dvbbasebin,
    const gchar * filename, const gchar * channel_name, GError ** error);
static GstDvbChannelConfFormat detect_file_format (const gchar * filename);

static gboolean gst_dvb_base_bin_conf_set_string (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static gboolean gst_dvb_base_bin_conf_set_uint (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static gboolean gst_dvb_base_bin_conf_set_int (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static gboolean gst_dvb_base_bin_conf_set_inversion (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static gboolean gst_dvb_base_bin_conf_set_guard (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static gboolean gst_dvb_base_bin_conf_set_trans_mode (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static gboolean gst_dvb_base_bin_conf_set_code_rate (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static gboolean gst_dvb_base_bin_conf_set_delsys (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static gboolean gst_dvb_base_bin_conf_set_hierarchy (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static gboolean gst_dvb_base_bin_conf_set_modulation (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key);
static GHashTable *parse_channels_conf_from_zap_file (GstElement * dvbbasebin,
    const gchar * filename, GError ** error);
static gboolean remove_channel_from_hash (gpointer key, gpointer value,
    gpointer user_data);
static void destroy_channels_hash (GHashTable * channels);

GstDvbV5ChannelsConfToPropertyMap dvbv5_prop_map[] = {
  {"SERVICE_ID", "program-numbers", gst_dvb_base_bin_conf_set_string},
  {"FREQUENCY", "frequency", gst_dvb_base_bin_conf_set_uint},
  {"BANDWIDTH_HZ", "bandwidth-hz", gst_dvb_base_bin_conf_set_uint},
  {"INVERSION", "inversion", gst_dvb_base_bin_conf_set_inversion},
  {"GUARD_INTERVAL", "guard", gst_dvb_base_bin_conf_set_guard},
  {"TRANSMISSION_MODE", "trans-mode", gst_dvb_base_bin_conf_set_trans_mode},
  {"HIERARCHY", "hierarchy", gst_dvb_base_bin_conf_set_hierarchy},
  {"MODULATION", "modulation", gst_dvb_base_bin_conf_set_modulation},
  {"CODE_RATE_HP", "code-rate-hp", gst_dvb_base_bin_conf_set_code_rate},
  {"CODE_RATE_LP", "code-rate-lp", gst_dvb_base_bin_conf_set_code_rate},
  {"ISDBT_LAYER_ENABLED", "isdbt-layer-enabled",
      gst_dvb_base_bin_conf_set_uint},
  {"ISDBT_PARTIAL_RECEPTION", "isdbt-partial-reception",
      gst_dvb_base_bin_conf_set_int},
  {"ISDBT_SOUND_BROADCASTING", "isdbt-sound-broadcasting",
      gst_dvb_base_bin_conf_set_int},
  {"ISDBT_SB_SUBCHANNEL_ID", "isdbt-sb-subchannel-id",
      gst_dvb_base_bin_conf_set_int},
  {"ISDBT_SB_SEGMENT_IDX", "isdbt-sb-segment-idx",
      gst_dvb_base_bin_conf_set_int},
  {"ISDBT_SB_SEGMENT_COUNT", "isdbt-sb-segment-count", gst_dvb_base_bin_conf_set_int},  /* Range in files start from 0, property starts from 1 */
  {"ISDBT_LAYERA_FEC", "isdbt-layera-fec", gst_dvb_base_bin_conf_set_code_rate},
  {"ISDBT_LAYERA_MODULATION", "isdbt-layera-modulation",
      gst_dvb_base_bin_conf_set_modulation},
  {"ISDBT_LAYERA_SEGMENT_COUNT", "isdbt-layera-segment-count",
      gst_dvb_base_bin_conf_set_int},
  {"ISDBT_LAYERA_TIME_INTERLEAVING", "isdbt-layera-time-interleaving",
      gst_dvb_base_bin_conf_set_int},
  {"ISDBT_LAYERB_FEC", "isdbt-layerb-fec", gst_dvb_base_bin_conf_set_code_rate},
  {"ISDBT_LAYERB_MODULATION", "isdbt-layerb-modulation",
      gst_dvb_base_bin_conf_set_modulation},
  {"ISDBT_LAYERB_SEGMENT_COUNT", "isdbt-layerb-segment-count",
      gst_dvb_base_bin_conf_set_int},
  {"ISDBT_LAYERB_TIME_INTERLEAVING", "isdbt-layerb-time-interleaving",
      gst_dvb_base_bin_conf_set_int},
  {"ISDBT_LAYERC_FEC", "isdbt-layerc-fec", gst_dvb_base_bin_conf_set_code_rate},
  {"ISDBT_LAYERC_MODULATION", "isdbt-layerc-modulation",
      gst_dvb_base_bin_conf_set_modulation},
  {"ISDBT_LAYERC_SEGMENT_COUNT", "isdbt-layerc-segment-count",
      gst_dvb_base_bin_conf_set_int},
  {"ISDBT_LAYERC_TIME_INTERLEAVING", "isdbt-layerc-time-interleaving",
      gst_dvb_base_bin_conf_set_int},
  {"DELIVERY_SYSTEM", "delsys", gst_dvb_base_bin_conf_set_delsys},
  {NULL,}
};

/* TODO:
 * Store the channels hash table around instead of constantly parsing it
 * Detect when the file changed on disk
 */

static gint
gst_dvb_base_bin_find_string_in_array (const gchar ** array, const gchar * str)
{
  gint i = 0;
  const gchar *cur;
  while ((cur = array[i])) {
    if (strcmp (cur, str) == 0)
      return i;

    i++;
  }

  return -1;
}

static gboolean
gst_dvb_base_bin_conf_set_property_from_string_array (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key, const gchar ** strings, gint default_value)
{
  gchar *str;
  gint v;

  str = g_key_file_get_string (kf, channel_name, key, NULL);
  v = gst_dvb_base_bin_find_string_in_array (strings, str);
  if (v == -1) {
    GST_WARNING_OBJECT (dvbbasebin, "Unexpected value '%s' for property "
        "'%s', using default: '%d'", str, property, default_value);
    v = default_value;
  }

  g_free (str);
  g_object_set (dvbbasebin, property, v, NULL);
  return TRUE;
}

static gboolean
gst_dvb_base_bin_conf_set_string (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key)
{
  gchar *str;

  str = g_key_file_get_string (kf, channel_name, key, NULL);
  if (!str) {
    GST_WARNING_OBJECT (dvbbasebin,
        "Could not get value for '%s' on channel '%s'", key, channel_name);
    return FALSE;
  }

  g_object_set (dvbbasebin, property, str, NULL);
  g_free (str);
  return TRUE;
}

static gboolean
gst_dvb_base_bin_conf_set_uint (GstElement * dvbbasebin, const gchar * property,
    GKeyFile * kf, const gchar * channel_name, const gchar * key)
{
  guint64 v;

  v = g_key_file_get_uint64 (kf, channel_name, key, NULL);
  if (!v) {
    GST_WARNING_OBJECT (dvbbasebin,
        "Could not get value for '%s' on channel '%s'", key, channel_name);
    return FALSE;
  }

  g_object_set (dvbbasebin, property, (guint) v, NULL);
  return TRUE;
}

static gboolean
gst_dvb_base_bin_conf_set_int (GstElement * dvbbasebin, const gchar * property,
    GKeyFile * kf, const gchar * channel_name, const gchar * key)
{
  gint v;

  v = g_key_file_get_integer (kf, channel_name, key, NULL);
  if (!v) {
    GST_WARNING_OBJECT (dvbbasebin,
        "Could not get value for '%s' on channel '%s'", key, channel_name);
    return FALSE;
  }

  g_object_set (dvbbasebin, property, v, NULL);
  return TRUE;
}

static gboolean
gst_dvb_base_bin_conf_set_inversion (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key)
{
  gchar *str;
  gint v;

  str = g_key_file_get_string (kf, channel_name, key, NULL);
  if (!str) {
    GST_WARNING_OBJECT (dvbbasebin,
        "Could not get value for '%s' on channel '%s'", key, channel_name);
    return FALSE;
  }

  if (strcmp (str, "AUTO") == 0)
    v = 2;
  else if (strcmp (str, "ON") == 0)
    v = 1;
  else
    v = 0;                      /* OFF */

  g_free (str);
  g_object_set (dvbbasebin, property, v, NULL);
  return TRUE;
}

static gboolean
gst_dvb_base_bin_conf_set_guard (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key)
{
  const gchar *guards[] = {
    "1/32", "1/16", "1/8", "1/4", "auto",
    "1/128", "19/128", "19/256",
    "PN420", "PN595", "PN945", NULL
  };
  return gst_dvb_base_bin_conf_set_property_from_string_array (dvbbasebin,
      property, kf, channel_name, key, guards, 4);
}

static gboolean
gst_dvb_base_bin_conf_set_trans_mode (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key)
{
  const gchar *trans_modes[] = {
    "2K", "8K", "AUTO", "4K", "1K",
    "16K", "32K", "C1", "C3780", NULL
  };
  return gst_dvb_base_bin_conf_set_property_from_string_array (dvbbasebin,
      property, kf, channel_name, key, trans_modes, 2);
}

static gboolean
gst_dvb_base_bin_conf_set_code_rate (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key)
{
  const gchar *code_rates[] = {
    "NONE", "1/2", "2/3", "3/4", "4/5",
    "5/6", "6/7", "7/8", "8/9", "AUTO",
    "3/5", "9/10", "2/5", NULL
  };
  return gst_dvb_base_bin_conf_set_property_from_string_array (dvbbasebin,
      property, kf, channel_name, key, code_rates, 9);
}

static gboolean
gst_dvb_base_bin_conf_set_delsys (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key)
{
  const gchar *delsys[] = {
    "UNDEFINED", "DVBCA", "DVBCB", "DVBT", "DSS",
    "DVBS", "DVBS2", "DVBH", "ISDBT", "ISDBS",
    "ISDBC", "ATSC", "ATSCMH", "DTMB", "CMMB",
    "DAB", "DVBT2", "TURBO", "DVBCC", NULL
  };
  return gst_dvb_base_bin_conf_set_property_from_string_array (dvbbasebin,
      property, kf, channel_name, key, delsys, 0);
}

static gboolean
gst_dvb_base_bin_conf_set_hierarchy (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key)
{
  const gchar *hierarchies[] = {
    "NONE", "1", "2", "4", "AUTO", NULL
  };
  return gst_dvb_base_bin_conf_set_property_from_string_array (dvbbasebin,
      property, kf, channel_name, key, hierarchies, 4);
}

static gboolean
gst_dvb_base_bin_conf_set_modulation (GstElement * dvbbasebin,
    const gchar * property, GKeyFile * kf, const gchar * channel_name,
    const gchar * key)
{
  const gchar *modulations[] = {
    "QPSK", "QAM/16", "QAM/32", "QAM/64",
    "QAM/128", "QAM/256", "QAM/AUTO", "VSB/8",
    "VSB/16", "PSK/8", "APSK/16", "APSK/32",
    "DQPSK", "QAM/4_NR", NULL
  };
  return gst_dvb_base_bin_conf_set_property_from_string_array (dvbbasebin,
      property, kf, channel_name, key, modulations, 6);
}

/* FIXME: is channel_name guaranteed to be ASCII or UTF-8? */
static gboolean
parse_and_configure_from_v5_conf_file (GstElement * dvbbasebin,
    const gchar * filename, const gchar * channel_name, GError ** error)
{
  GKeyFile *keyfile;
  gchar **keys, **keys_p;
  GError *err = NULL;

  keyfile = g_key_file_new ();
  if (!g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, &err))
    goto load_error;

  if (!g_key_file_has_group (keyfile, channel_name))
    goto unknown_channel;

  keys = g_key_file_get_keys (keyfile, channel_name, NULL, &err);
  if (!keys)
    goto no_properties;

  keys_p = keys;
  while (*keys_p) {
    const gchar *k = *keys_p;
    const GstDvbV5ChannelsConfToPropertyMap *map_entry = dvbv5_prop_map;
    gboolean property_found = FALSE;

    GST_LOG_OBJECT (dvbbasebin, "Setting property %s", k);

    while (map_entry->conf_property) {
      if (strcmp (map_entry->conf_property, k) == 0) {
        if (!map_entry->set_func (dvbbasebin, map_entry->elem_property, keyfile,
                channel_name, k))
          goto property_error;
        property_found = TRUE;
        break;
      }
      map_entry++;
    }

    if (!property_found)
      GST_WARNING_OBJECT (dvbbasebin, "Failed to map property '%s'", k);

    keys_p++;
  }

  GST_DEBUG_OBJECT (dvbbasebin, "Successfully parsed channel configuration "
      "file '%s'", filename);
  g_strfreev (keys);
  g_key_file_unref (keyfile);
  return TRUE;

load_error:
  if ((err->domain == G_FILE_ERROR && err->code == G_FILE_ERROR_NOENT) ||
      (err->domain == G_KEY_FILE_ERROR
          && err->code == G_KEY_FILE_ERROR_NOT_FOUND)) {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_FOUND,
        _("Couldn't find channel configuration file"));
  } else {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
        _("Couldn't load channel configuration file: '%s'"), err->message);
  }
  g_clear_error (&err);
  return FALSE;

unknown_channel:
  {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_FOUND,
        _("Couldn't find details for channel '%s'"), channel_name);
    g_key_file_unref (keyfile);
    g_clear_error (&err);
    return FALSE;
  }

no_properties:
  {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_FOUND,
        _("No properties for channel '%s'"), channel_name);
    g_key_file_unref (keyfile);
    g_clear_error (&err);
    return FALSE;
  }

property_error:
  {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
        _("Failed to set properties for channel '%s'"), channel_name);
    g_key_file_unref (keyfile);
    g_clear_error (&err);
    return FALSE;
  }
}

static GHashTable *
parse_channels_conf_from_zap_file (GstElement * dvbbasebin,
    const gchar * filename, GError ** error)
{
  gchar *contents;
  gchar **lines;
  gchar *line;
  gchar **fields;
  int i, parsedchannels = 0;
  GHashTable *res;
  GError *err = NULL;
  const gchar *terrestrial[] = { "inversion", "bandwidth",
    "code-rate-hp", "code-rate-lp", "modulation", "transmission-mode",
    "guard", "hierarchy"
  };
  const gchar *satellite[] = { "polarity", "diseqc-source",
    "symbol-rate"
  };
  const gchar *cable[] = { "inversion", "symbol-rate", "code-rate-hp",
    "modulation"
  };

  GST_INFO_OBJECT (dvbbasebin, "parsing '%s'", filename);

  if (!g_file_get_contents (filename, &contents, NULL, &err))
    goto open_fail;

  lines = g_strsplit (contents, "\n", 0);
  res = g_hash_table_new (g_str_hash, g_str_equal);

  i = 0;
  line = lines[0];
  while (line != NULL) {
    GHashTable *params;
    int j, numfields;

    if (line[0] == '#')
      goto next_line;

    params = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
    fields = g_strsplit (line, ":", 0);
    numfields = g_strv_length (fields);

    switch (numfields) {
      case 13:                 /* terrestrial */
        g_hash_table_insert (params, g_strdup ("type"),
            g_strdup ("terrestrial"));
        for (j = 2; j <= 9; j++) {
          g_hash_table_insert (params, g_strdup (terrestrial[j - 2]),
              g_strdup (fields[j]));
        }
        g_hash_table_insert (params, g_strdup ("frequency"),
            g_strdup (fields[1]));
        break;
      case 9:                  /* cable */
        g_hash_table_insert (params, g_strdup ("type"), g_strdup ("cable"));
        for (j = 2; j <= 5; j++) {
          g_hash_table_insert (params, g_strdup (cable[j - 2]),
              g_strdup (fields[j]));
        }
        g_hash_table_insert (params, g_strdup ("frequency"),
            g_strdup (fields[1]));
        break;
      case 8:                  /* satellite */
        g_hash_table_insert (params, g_strdup ("type"), g_strdup ("satellite"));
        for (j = 2; j <= 4; j++) {
          g_hash_table_insert (params, g_strdup (satellite[j - 2]),
              g_strdup (fields[j]));
        }
        /* Some ZAP format variations store freqs in MHz
         * but we internally use kHz for DVB-S/S2. */
        if (strlen (fields[1]) < 6) {
          g_hash_table_insert (params, g_strdup ("frequency"),
              g_strdup_printf ("%d", atoi (fields[1]) * 1000));
        } else {
          g_hash_table_insert (params, g_strdup ("frequency"),
              g_strdup_printf ("%d", atoi (fields[1])));
        }
        break;
      case 6:                  /* atsc (vsb/qam) */
        g_hash_table_insert (params, g_strdup ("type"), g_strdup ("atsc"));
        g_hash_table_insert (params, g_strdup ("modulation"),
            g_strdup (fields[2]));

        g_hash_table_insert (params, g_strdup ("frequency"),
            g_strdup (fields[1]));
        break;
      default:
        goto not_parsed;
    }

    /* parsed */
    g_hash_table_insert (params, g_strdup ("sid"),
        g_strdup (fields[numfields - 1]));
    g_hash_table_insert (res, g_strdup (fields[0]), params);
    parsedchannels++;

  not_parsed:
    g_strfreev (fields);
  next_line:
    line = lines[++i];
  }

  g_strfreev (lines);
  g_free (contents);

  if (parsedchannels == 0)
    goto no_channels;

  return res;

open_fail:
  if (err->code == G_FILE_ERROR_NOENT) {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_FOUND,
        _("Couldn't find channel configuration file: '%s'"), err->message);
  } else {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
        _("Couldn't load channel configuration file: '%s'"), err->message);
  }
  g_clear_error (&err);
  return NULL;

no_channels:
  g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
      _("Channel configuration file doesn't contain any channels"));
  g_hash_table_unref (res);
  return NULL;
}

static gboolean
remove_channel_from_hash (gpointer key, gpointer value, gpointer user_data)
{
  g_free (key);
  if (value)
    g_hash_table_destroy ((GHashTable *) value);
  return TRUE;
}

static void
destroy_channels_hash (GHashTable * channels)
{
  g_hash_table_foreach_remove (channels, remove_channel_from_hash, NULL);
}

/* FIXME: is channel_name guaranteed to be ASCII or UTF-8? */
static gboolean
parse_and_configure_from_zap_conf_file (GstElement * dvbbasebin,
    const gchar * filename, const gchar * channel_name, GError ** error)
{
  gboolean ret = FALSE;
  GHashTable *channels, *params;
  gchar *type;

  /* Assumptions are made here about a format that is loosely
   * defined. Particularly, we assume a given delivery system
   * out of counting the number of fields per line. dvbsrc has
   * smarter code to auto-detect a delivery system based on
   * known-correct combinations of parameters so if you ever
   * encounter cases where the delivery system is being
   * wrongly set here, just remove the offending
   * g_object_set line and let dvbsrc work his magic out. */

  channels = parse_channels_conf_from_zap_file (dvbbasebin, filename, error);

  if (!channels)
    goto beach;

  params = g_hash_table_lookup (channels, channel_name);

  if (!params)
    goto unknown_channel;

  g_object_set (dvbbasebin, "program-numbers",
      g_hash_table_lookup (params, "sid"), NULL);
  /* check if it is terrestrial or satellite */
  g_object_set (dvbbasebin, "frequency",
      atoi (g_hash_table_lookup (params, "frequency")), NULL);
  type = g_hash_table_lookup (params, "type");
  if (strcmp (type, "terrestrial") == 0) {
    gchar *val;

    val = g_hash_table_lookup (params, "inversion");
    if (strcmp (val, "INVERSION_OFF") == 0)
      g_object_set (dvbbasebin, "inversion", INVERSION_OFF, NULL);
    else if (strcmp (val, "INVERSION_ON") == 0)
      g_object_set (dvbbasebin, "inversion", INVERSION_ON, NULL);
    else
      g_object_set (dvbbasebin, "inversion", INVERSION_AUTO, NULL);

    val = g_hash_table_lookup (params, "bandwidth");
    if (strcmp (val, "BANDWIDTH_8_MHZ") == 0)
      g_object_set (dvbbasebin, "bandwidth", 0, NULL);
    else if (strcmp (val, "BANDWIDTH_7_MHZ") == 0)
      g_object_set (dvbbasebin, "bandwidth", 1, NULL);
    else if (strcmp (val, "BANDWIDTH_6_MHZ") == 0)
      g_object_set (dvbbasebin, "bandwidth", 2, NULL);
    else if (strcmp (val, "BANDWIDTH_5_MHZ") == 0)
      g_object_set (dvbbasebin, "bandwidth", 4, NULL);
    else if (strcmp (val, "BANDWIDTH_10_MHZ") == 0)
      g_object_set (dvbbasebin, "bandwidth", 5, NULL);
    else if (strcmp (val, "BANDWIDTH_1_712_MHZ") == 0)
      g_object_set (dvbbasebin, "bandwidth", 6, NULL);
    else
      g_object_set (dvbbasebin, "bandwidth", 3, NULL);

    val = g_hash_table_lookup (params, "code-rate-hp");
    if (strcmp (val, "FEC_NONE") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 0, NULL);
    else if (strcmp (val, "FEC_1_2") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 1, NULL);
    else if (strcmp (val, "FEC_2_3") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 2, NULL);
    else if (strcmp (val, "FEC_3_4") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 3, NULL);
    else if (strcmp (val, "FEC_4_5") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 4, NULL);
    else if (strcmp (val, "FEC_5_6") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 5, NULL);
    else if (strcmp (val, "FEC_6_7") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 6, NULL);
    else if (strcmp (val, "FEC_7_8") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 7, NULL);
    else if (strcmp (val, "FEC_8_9") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 8, NULL);
    else
      g_object_set (dvbbasebin, "code-rate-hp", 9, NULL);

    val = g_hash_table_lookup (params, "code-rate-lp");
    if (strcmp (val, "FEC_NONE") == 0)
      g_object_set (dvbbasebin, "code-rate-lp", 0, NULL);
    else if (strcmp (val, "FEC_1_2") == 0)
      g_object_set (dvbbasebin, "code-rate-lp", 1, NULL);
    else if (strcmp (val, "FEC_2_3") == 0)
      g_object_set (dvbbasebin, "code-rate-lp", 2, NULL);
    else if (strcmp (val, "FEC_3_4") == 0)
      g_object_set (dvbbasebin, "code-rate-lp", 3, NULL);
    else if (strcmp (val, "FEC_4_5") == 0)
      g_object_set (dvbbasebin, "code-rate-lp", 4, NULL);
    else if (strcmp (val, "FEC_5_6") == 0)
      g_object_set (dvbbasebin, "code-rate-lp", 5, NULL);
    else if (strcmp (val, "FEC_6_7") == 0)
      g_object_set (dvbbasebin, "code-rate-lp", 6, NULL);
    else if (strcmp (val, "FEC_7_8") == 0)
      g_object_set (dvbbasebin, "code-rate-lp", 7, NULL);
    else if (strcmp (val, "FEC_8_9") == 0)
      g_object_set (dvbbasebin, "code-rate-lp", 8, NULL);
    else
      g_object_set (dvbbasebin, "code-rate-lp", 9, NULL);

    val = g_hash_table_lookup (params, "modulation");
    if (strcmp (val, "QPSK") == 0)
      g_object_set (dvbbasebin, "modulation", 0, NULL);
    else if (strcmp (val, "QAM_16") == 0)
      g_object_set (dvbbasebin, "modulation", 1, NULL);
    else if (strcmp (val, "QAM_32") == 0)
      g_object_set (dvbbasebin, "modulation", 2, NULL);
    else if (strcmp (val, "QAM_64") == 0)
      g_object_set (dvbbasebin, "modulation", 3, NULL);
    else if (strcmp (val, "QAM_128") == 0)
      g_object_set (dvbbasebin, "modulation", 4, NULL);
    else if (strcmp (val, "QAM_256") == 0)
      g_object_set (dvbbasebin, "modulation", 5, NULL);
    else
      g_object_set (dvbbasebin, "modulation", 6, NULL);

    val = g_hash_table_lookup (params, "transmission-mode");
    if (strcmp (val, "TRANSMISSION_MODE_2K") == 0)
      g_object_set (dvbbasebin, "trans-mode", 0, NULL);
    else if (strcmp (val, "TRANSMISSION_MODE_8K") == 0)
      g_object_set (dvbbasebin, "trans-mode", 1, NULL);
    else
      g_object_set (dvbbasebin, "trans-mode", 2, NULL);

    val = g_hash_table_lookup (params, "guard");
    if (strcmp (val, "GUARD_INTERVAL_1_32") == 0)
      g_object_set (dvbbasebin, "guard", 0, NULL);
    else if (strcmp (val, "GUARD_INTERVAL_1_16") == 0)
      g_object_set (dvbbasebin, "guard", 1, NULL);
    else if (strcmp (val, "GUARD_INTERVAL_1_8") == 0)
      g_object_set (dvbbasebin, "guard", 2, NULL);
    else if (strcmp (val, "GUARD_INTERVAL_1_4") == 0)
      g_object_set (dvbbasebin, "guard", 3, NULL);
    else
      g_object_set (dvbbasebin, "guard", 4, NULL);

    val = g_hash_table_lookup (params, "hierarchy");
    if (strcmp (val, "HIERARCHY_NONE") == 0)
      g_object_set (dvbbasebin, "hierarchy", 0, NULL);
    else if (strcmp (val, "HIERARCHY_1") == 0)
      g_object_set (dvbbasebin, "hierarchy", 1, NULL);
    else if (strcmp (val, "HIERARCHY_2") == 0)
      g_object_set (dvbbasebin, "hierarchy", 2, NULL);
    else if (strcmp (val, "HIERARCHY_4") == 0)
      g_object_set (dvbbasebin, "hierarchy", 3, NULL);
    else
      g_object_set (dvbbasebin, "hierarchy", 4, NULL);

    ret = TRUE;
  } else if (strcmp (type, "satellite") == 0) {
    gchar *val;

    ret = TRUE;

    g_object_set (dvbbasebin, "delsys", SYS_DVBS, NULL);

    val = g_hash_table_lookup (params, "polarity");
    if (val)
      g_object_set (dvbbasebin, "polarity", val, NULL);
    else
      ret = FALSE;

    val = g_hash_table_lookup (params, "diseqc-source");
    if (val)
      g_object_set (dvbbasebin, "diseqc-source", atoi (val), NULL);

    val = g_hash_table_lookup (params, "symbol-rate");
    if (val)
      g_object_set (dvbbasebin, "symbol-rate", atoi (val), NULL);
    else
      ret = FALSE;
  } else if (strcmp (type, "cable") == 0) {
    gchar *val;

    g_object_set (dvbbasebin, "delsys", SYS_DVBC_ANNEX_A, NULL);

    ret = TRUE;
    val = g_hash_table_lookup (params, "symbol-rate");
    if (val)
      g_object_set (dvbbasebin, "symbol-rate", atoi (val) / 1000, NULL);
    val = g_hash_table_lookup (params, "modulation");
    if (strcmp (val, "QPSK") == 0)
      g_object_set (dvbbasebin, "modulation", 0, NULL);
    else if (strcmp (val, "QAM_16") == 0)
      g_object_set (dvbbasebin, "modulation", 1, NULL);
    else if (strcmp (val, "QAM_32") == 0)
      g_object_set (dvbbasebin, "modulation", 2, NULL);
    else if (strcmp (val, "QAM_64") == 0)
      g_object_set (dvbbasebin, "modulation", 3, NULL);
    else if (strcmp (val, "QAM_128") == 0)
      g_object_set (dvbbasebin, "modulation", 4, NULL);
    else if (strcmp (val, "QAM_256") == 0)
      g_object_set (dvbbasebin, "modulation", 5, NULL);
    else
      g_object_set (dvbbasebin, "modulation", 6, NULL);
    val = g_hash_table_lookup (params, "code-rate-hp");
    if (strcmp (val, "FEC_NONE") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 0, NULL);
    else if (strcmp (val, "FEC_1_2") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 1, NULL);
    else if (strcmp (val, "FEC_2_3") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 2, NULL);
    else if (strcmp (val, "FEC_3_4") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 3, NULL);
    else if (strcmp (val, "FEC_4_5") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 4, NULL);
    else if (strcmp (val, "FEC_5_6") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 5, NULL);
    else if (strcmp (val, "FEC_6_7") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 6, NULL);
    else if (strcmp (val, "FEC_7_8") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 7, NULL);
    else if (strcmp (val, "FEC_8_9") == 0)
      g_object_set (dvbbasebin, "code-rate-hp", 8, NULL);
    else
      g_object_set (dvbbasebin, "code-rate-hp", 9, NULL);
    val = g_hash_table_lookup (params, "inversion");
    if (strcmp (val, "INVERSION_OFF") == 0)
      g_object_set (dvbbasebin, "inversion", 0, NULL);
    else if (strcmp (val, "INVERSION_ON") == 0)
      g_object_set (dvbbasebin, "inversion", 1, NULL);
    else
      g_object_set (dvbbasebin, "inversion", 2, NULL);
  } else if (strcmp (type, "atsc") == 0) {
    gchar *val;

    ret = TRUE;

    g_object_set (dvbbasebin, "delsys", SYS_ATSC, NULL);

    val = g_hash_table_lookup (params, "modulation");
    if (strcmp (val, "QAM_64") == 0)
      g_object_set (dvbbasebin, "modulation", 3, NULL);
    else if (strcmp (val, "QAM_256") == 0)
      g_object_set (dvbbasebin, "modulation", 5, NULL);
    else if (strcmp (val, "8VSB") == 0)
      g_object_set (dvbbasebin, "modulation", 7, NULL);
    else if (strcmp (val, "16VSB") == 0)
      g_object_set (dvbbasebin, "modulation", 8, NULL);
    else
      ret = FALSE;
  }

  destroy_channels_hash (channels);

beach:
  return ret;

unknown_channel:
  {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_FOUND,
        _("Couldn't find details for channel '%s'"), channel_name);
    destroy_channels_hash (channels);
    return FALSE;
  }
}

static GstDvbChannelConfFormat
detect_file_format (const gchar * filename)
{
  gchar *contents;
  gchar **lines;
  gchar **line;
  GstDvbChannelConfFormat ret = CHANNEL_CONF_FORMAT_NONE;

  if (!g_file_get_contents (filename, &contents, NULL, NULL))
    return ret;

  lines = g_strsplit (contents, "\n", 0);
  line = lines;

  while (*line) {
    if (g_str_has_prefix (*line, "[") && g_str_has_suffix (*line, "]")) {
      ret = CHANNEL_CONF_FORMAT_DVBV5;
      break;
    } else if (g_strrstr (*line, ":")) {
      ret = CHANNEL_CONF_FORMAT_ZAP;
      break;
    }
    line++;
  }

  g_strfreev (lines);
  g_free (contents);
  return ret;
}

gboolean
set_properties_for_channel (GstElement * dvbbasebin,
    const gchar * channel_name, GError ** error)
{
  gboolean ret = FALSE;
  gchar *filename;
  const gchar *adapter;

  filename = g_strdup (g_getenv ("GST_DVB_CHANNELS_CONF"));
  if (filename == NULL) {
    filename = g_build_filename (g_get_user_config_dir (),
        "gstreamer-" GST_API_VERSION, "dvb-channels.conf", NULL);
  }

  adapter = g_getenv ("GST_DVB_ADAPTER");
  if (adapter)
    g_object_set (dvbbasebin, "adapter", atoi (adapter), NULL);

  switch (detect_file_format (filename)) {
    case CHANNEL_CONF_FORMAT_DVBV5:
      if (!parse_and_configure_from_v5_conf_file (dvbbasebin, filename,
              channel_name, error)) {
        GST_WARNING_OBJECT (dvbbasebin, "Could not parse libdvbv5 channel "
            "configuration file '%s'", filename);
      } else {
        GST_INFO_OBJECT (dvbbasebin, "Parsed libdvbv5 channel configuration "
            "file");
        ret = TRUE;
      }
      break;
    case CHANNEL_CONF_FORMAT_ZAP:
      if (!parse_and_configure_from_zap_conf_file (dvbbasebin, filename,
              channel_name, error)) {
        GST_WARNING_OBJECT (dvbbasebin, "Could not parse ZAP channel "
            "configuration file '%s'", filename);
      } else {
        GST_INFO_OBJECT (dvbbasebin, "Parsed ZAP channel configuration file");
        ret = TRUE;
      }
      break;
    default:
      GST_WARNING_OBJECT (dvbbasebin, "Unknown configuration file format. "
          "Can not get parameters for channel");
  }

  g_free (filename);
  return ret;
}
