/*
 * 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>

typedef enum
{
  CHANNEL_CONF_FORMAT_NONE,
  CHANNEL_CONF_FORMAT_DVBV5,
  CHANNEL_CONF_FORMAT_ZAP
} GstDvbChannelConfFormat;

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);


GST_DEBUG_CATEGORY_EXTERN (dvb_base_bin_debug);
#define GST_CAT_DEFAULT dvb_base_bin_debug

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

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

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[] = {
    "32", "16", "8", "4", "auto",
    "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_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);
}

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

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},
  {"MODULATION", "modulation", gst_dvb_base_bin_conf_set_modulation},
  {"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,}
};

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 DVB channel configuration file"));
  } else {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
        _("Couldn't load DVB channel configuration file: %s"), err->message);
  }
  g_clear_error (&err);
  return FALSE;

unknown_channel:
  {
    /* FIXME: is channel name guaranteed to be ASCII or UTF-8? */
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_FOUND,
        _("Couldn't find details for DVB channel %s"), channel_name);
    g_key_file_unref (keyfile);
    g_clear_error (&err);
    return FALSE;
  }

no_properties:
  {
    /* FIXME: is channel name guaranteed to be ASCII or UTF-8? */
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_FOUND,
        _("No properties for the DVB channel %s"), channel_name);
    g_key_file_unref (keyfile);
    g_clear_error (&err);
    return FALSE;
  }

property_error:
  {
    /* FIXME: is channel name guaranteed to be ASCII or UTF-8? */
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
        _("Failed to set properties for the DVB channel %s"), channel_name);
    g_key_file_unref (keyfile);
    g_clear_error (&err);
    return FALSE;
  }
}

/* this will do zap style channels.conf only for the moment */
static GHashTable *
parse_channels_conf_from_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 DVB channel configuration file: %s"), err->message);
  } else {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
        _("Couldn't load DVB 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,
      _("DVB 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);
}

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_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:
  {
    /* FIXME: is channel name guaranteed to be ASCII or UTF-8? */
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_NOT_FOUND,
        _("Couldn't find details for DVB 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;
}
