/*
 * Copyright (C) <2008> Jacob Meuser <jakemsr@sdf.lonestar.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/**
 * SECTION:element-sndiosrc
 * @see_also: #GstAutoAudioSrc
 *
 * <refsect2>
 * <para>
 * This element retrieves samples from a sound card using sndio.
 * </para>
 * <para>
 * Simple example pipeline that records an Ogg/Vorbis file via sndio:
 * <programlisting>
 * gst-launch-1.0 -v sndiosrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=foo.ogg
 * </programlisting>
 * </para>
 * </refsect2>
 */

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

#include "sndiosrc.h"
#include <unistd.h>
#include <errno.h>

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

GST_DEBUG_CATEGORY_EXTERN (gst_sndio_debug);
#define GST_CAT_DEFAULT gst_sndio_debug

enum
{
  PROP_0,
  PROP_HOST
};

static GstStaticPadTemplate sndio_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw-int, "
        "endianness = (int) { 1234, 4321 }, "
        "signed = (boolean) { TRUE, FALSE }, "
        "width = (int) { 8, 16, 24, 32 }, "
        "depth = (int) { 8, 16, 24, 32 }, "
        "rate = (int) [ 8000, 192000 ], " "channels = (int) [ 1, 16 ] ")
    );

static void gst_sndiosrc_finalize (GObject * object);

static GstCaps *gst_sndiosrc_getcaps (GstBaseSrc * bsrc);

static gboolean gst_sndiosrc_open (GstAudioSrc * asrc);
static gboolean gst_sndiosrc_close (GstAudioSrc * asrc);
static gboolean gst_sndiosrc_prepare (GstAudioSrc * asrc,
    GstRingBufferSpec * spec);
static gboolean gst_sndiosrc_unprepare (GstAudioSrc * asrc);
static guint gst_sndiosrc_read (GstAudioSrc * asrc, gpointer data,
    guint length);
static guint gst_sndiosrc_delay (GstAudioSrc * asrc);
static void gst_sndiosrc_reset (GstAudioSrc * asrc);

static void gst_sndiosrc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_sndiosrc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_sndiosrc_cb (void *addr, int delta);

GST_BOILERPLATE (GstSndioSrc, gst_sndiosrc, GstAudioSrc, GST_TYPE_AUDIO_SRC);

static void
gst_sndiosrc_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_set_static_metadata (element_class,
      "Sndio audio source",
      "Source/Audio",
      "Records audio through sndio", "Jacob Meuser <jakemsr@sdf.lonestar.org>");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sndio_src_factory));
}

static void
gst_sndiosrc_class_init (GstSndioSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstBaseSrcClass *gstbasesrc_class;
  GstBaseAudioSrcClass *gstbaseaudiosrc_class;
  GstAudioSrcClass *gstaudiosrc_class;

  gobject_class = (GObjectClass *) klass;
  gstbasesrc_class = (GstBaseSrcClass *) klass;
  gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
  gstaudiosrc_class = (GstAudioSrcClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = gst_sndiosrc_finalize;

  gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_sndiosrc_getcaps);

  gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_sndiosrc_open);
  gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_sndiosrc_close);
  gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_sndiosrc_prepare);
  gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_sndiosrc_unprepare);
  gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_sndiosrc_read);
  gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_sndiosrc_delay);
  gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_sndiosrc_reset);

  gobject_class->set_property = gst_sndiosrc_set_property;
  gobject_class->get_property = gst_sndiosrc_get_property;

  /* default value is filled in the _init method */
  g_object_class_install_property (gobject_class, PROP_HOST,
      g_param_spec_string ("host", "Host",
          "Device or socket sndio will access", NULL, G_PARAM_READWRITE));
}

static void
gst_sndiosrc_init (GstSndioSrc * sndiosrc, GstSndioSrcClass * klass)
{
  sndiosrc->hdl = NULL;
  sndiosrc->host = g_strdup (g_getenv ("AUDIODEVICE"));
}

static void
gst_sndiosrc_finalize (GObject * object)
{
  GstSndioSrc *sndiosrc = GST_SNDIOSRC (object);

  gst_caps_replace (&sndiosrc->cur_caps, NULL);
  g_free (sndiosrc->host);

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

static GstCaps *
gst_sndiosrc_getcaps (GstBaseSrc * bsrc)
{
  GstSndioSrc *sndiosrc;

  sndiosrc = GST_SNDIOSRC (bsrc);

  /* no hdl, we're done with the template caps */
  if (sndiosrc->cur_caps == NULL) {
    GST_LOG_OBJECT (sndiosrc, "getcaps called, returning template caps");
    return NULL;
  }

  GST_LOG_OBJECT (sndiosrc, "returning %" GST_PTR_FORMAT, sndiosrc->cur_caps);

  return gst_caps_ref (sndiosrc->cur_caps);
}

static gboolean
gst_sndiosrc_open (GstAudioSrc * asrc)
{
  GstPadTemplate *pad_template;
  GstSndioSrc *sndiosrc;
  struct sio_par par;
  struct sio_cap cap;
  GArray *rates, *chans;
  GValue rates_v = { 0 };
  GValue chans_v = { 0 };
  GValue value = { 0 };
  struct sio_enc enc;
  struct sio_conf conf;
  int confs[SIO_NCONF];
  int rate, chan;
  int i, j, k;
  int nconfs;

  sndiosrc = GST_SNDIOSRC (asrc);

  GST_DEBUG_OBJECT (sndiosrc, "open");

  /* connect */
  sndiosrc->hdl = sio_open (sndiosrc->host, SIO_REC, 0);

  if (sndiosrc->hdl == NULL)
    goto couldnt_connect;

  /* Use sndio defaults as the only encodings, but get the supported
   * sample rates and number of channels.
   */

  if (!sio_getpar (sndiosrc->hdl, &par))
    goto no_server_info;

  if (!sio_getcap (sndiosrc->hdl, &cap))
    goto no_server_info;

  rates = g_array_new (FALSE, FALSE, sizeof (int));
  chans = g_array_new (FALSE, FALSE, sizeof (int));

  /* find confs that have the default encoding */
  nconfs = 0;
  for (i = 0; i < cap.nconf; i++) {
    for (j = 0; j < SIO_NENC; j++) {
      if (cap.confs[i].enc & (1 << j)) {
        enc = cap.enc[j];
        if (enc.bits == par.bits && enc.sig == par.sig && enc.le == par.le) {
          confs[nconfs] = i;
          nconfs++;
          break;
        }
      }
    }
  }

  /* find the rates and channels of the confs that have the default encoding */
  for (i = 0; i < nconfs; i++) {
    conf = cap.confs[confs[i]];
    /* rates */
    for (j = 0; j < SIO_NRATE; j++) {
      if (conf.rate & (1 << j)) {
        rate = cap.rate[j];
        for (k = 0; k < rates->len && rate; k++) {
          if (rate == g_array_index (rates, int, k))
              rate = 0;
        }
        /* add in ascending order */
        if (rate) {
          for (k = 0; k < rates->len; k++) {
            if (rate < g_array_index (rates, int, k))
            {
              g_array_insert_val (rates, k, rate);
              break;
            }
          }
          if (k == rates->len)
            g_array_append_val (rates, rate);
        }
      }
    }
    /* channels */
    for (j = 0; j < SIO_NCHAN; j++) {
      if (conf.rchan & (1 << j)) {
        chan = cap.rchan[j];
        for (k = 0; k < chans->len && chan; k++) {
          if (chan == g_array_index (chans, int, k))
              chan = 0;
        }
        /* add in ascending order */
        if (chan) {
          for (k = 0; k < chans->len; k++) {
            if (chan < g_array_index (chans, int, k))
            {
              g_array_insert_val (chans, k, chan);
              break;
            }
          }
          if (k == chans->len)
            g_array_append_val (chans, chan);
        }
      }
    }
  }
  /* not sure how this can happen, but it might */
  if (cap.nconf == 0) {
    g_array_append_val (rates, par.rate);
    g_array_append_val (chans, par.rchan);
  }

  g_value_init (&rates_v, GST_TYPE_LIST);
  g_value_init (&chans_v, GST_TYPE_LIST);
  g_value_init (&value, G_TYPE_INT);

  for (i = 0; i < rates->len; i++) {
    g_value_set_int (&value, g_array_index (rates, int, i));
    gst_value_list_append_value (&rates_v, &value);
  }
  for (i = 0; i < chans->len; i++) {
    g_value_set_int (&value, g_array_index (chans, int, i));
    gst_value_list_append_value (&chans_v, &value);
  }

  g_array_free (rates, TRUE);
  g_array_free (chans, TRUE);

  pad_template = gst_static_pad_template_get (&sndio_src_factory);
  sndiosrc->cur_caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
  gst_object_unref (pad_template);

  for (i = 0; i < sndiosrc->cur_caps->structs->len; i++) {
    GstStructure *s;

    s = gst_caps_get_structure (sndiosrc->cur_caps, i);
    gst_structure_set (s, "endianness", G_TYPE_INT, par.le ? 1234 : 4321, NULL);
    gst_structure_set (s, "signed", G_TYPE_BOOLEAN, par.sig ? TRUE : FALSE,
        NULL);
    gst_structure_set (s, "width", G_TYPE_INT, par.bits, NULL);
    // gst_structure_set (s, "depth", G_TYPE_INT, par.bps * 8, NULL); /* XXX */
    gst_structure_set_value (s, "rate", &rates_v);
    gst_structure_set_value (s, "channels", &chans_v);
  }

  return TRUE;

  /* ERRORS */
couldnt_connect:
  {
    GST_ELEMENT_ERROR (sndiosrc, RESOURCE, OPEN_READ,
        (_("Could not establish connection to sndio")),
        ("can't open connection to sndio"));
    return FALSE;
  }
no_server_info:
  {
    GST_ELEMENT_ERROR (sndiosrc, RESOURCE, OPEN_READ,
        (_("Failed to query sndio capabilities")),
        ("couldn't get sndio info!"));
    return FALSE;
  }
}

static gboolean
gst_sndiosrc_close (GstAudioSrc * asrc)
{
  GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);

  GST_DEBUG_OBJECT (sndiosrc, "close");

  gst_caps_replace (&sndiosrc->cur_caps, NULL);
  sio_close (sndiosrc->hdl);
  sndiosrc->hdl = NULL;

  return TRUE;
}

static void
gst_sndiosrc_cb (void *addr, int delta)
{
  GstSndioSrc *sndiosrc = GST_SNDIOSRC ((GstAudioSrc *) addr);

  sndiosrc->realpos += delta;

  if (sndiosrc->readpos >= sndiosrc->realpos)
    sndiosrc->latency = 0;
  else
    sndiosrc->latency = sndiosrc->realpos - sndiosrc->readpos;
}

static gboolean
gst_sndiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
{
  GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);
  struct sio_par par;
  int spec_bpf;

  GST_DEBUG_OBJECT (sndiosrc, "prepare");

  sndiosrc->readpos = sndiosrc->realpos = sndiosrc->latency = 0;

  sio_initpar (&par);
  par.sig = spec->sign;
  par.le = !spec->bigend;
  par.bits = spec->width;
  // par.bps = spec->depth / 8;  /* XXX */
  par.rate = spec->rate;
  par.rchan = spec->channels;

  spec_bpf = ((spec->width / 8) * spec->channels);

  par.round = spec->segsize / spec_bpf;
  par.appbufsz = (spec->segsize * spec->segtotal) / spec_bpf;

  if (!sio_setpar (sndiosrc->hdl, &par))
    goto cannot_configure;

  sio_getpar (sndiosrc->hdl, &par);

  spec->sign = par.sig;
  spec->bigend = !par.le;
  spec->width = par.bits;
  // spec->depth = par.bps * 8;  /* XXX */
  spec->rate = par.rate;
  spec->channels = par.rchan;

  sndiosrc->bpf = par.bps * par.rchan;

  spec->segsize = par.round * par.rchan * par.bps;
  spec->segtotal = par.bufsz / par.round;

  /* FIXME: this is wrong for signed ints (and the
   * audioringbuffers should do it for us anyway) */
  spec->silence_sample[0] = 0;
  spec->silence_sample[1] = 0;
  spec->silence_sample[2] = 0;
  spec->silence_sample[3] = 0;

  sio_onmove (sndiosrc->hdl, gst_sndiosrc_cb, sndiosrc);

  if (!sio_start (sndiosrc->hdl))
    goto cannot_start;

  GST_INFO_OBJECT (sndiosrc, "successfully opened connection to sndio");

  return TRUE;

  /* ERRORS */
cannot_configure:
  {
    GST_ELEMENT_ERROR (sndiosrc, RESOURCE, OPEN_READ,
        (_("Could not configure sndio")), ("can't configure sndio"));
    return FALSE;
  }
cannot_start:
  {
    GST_ELEMENT_ERROR (sndiosrc, RESOURCE, OPEN_READ,
        (_("Could not start sndio")), ("can't start sndio"));
    return FALSE;
  }
}

static gboolean
gst_sndiosrc_unprepare (GstAudioSrc * asrc)
{
  GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);

  if (sndiosrc->hdl == NULL)
    return TRUE;

  sio_stop (sndiosrc->hdl);

  return TRUE;
}

static guint
gst_sndiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
{
  GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);
  guint done;

  done = sio_read (sndiosrc->hdl, data, length);

  if (done == 0)
    goto read_error;

  sndiosrc->readpos += (done / sndiosrc->bpf);

  data = (char *) data + done;

  return done;

  /* ERRORS */
read_error:
  {
    GST_ELEMENT_ERROR (sndiosrc, RESOURCE, READ,
        ("Failed to read data from sndio"), GST_ERROR_SYSTEM);
    return 0;
  }
}

static guint
gst_sndiosrc_delay (GstAudioSrc * asrc)
{
  GstSndioSrc *sndiosrc = GST_SNDIOSRC (asrc);

  if (sndiosrc->latency == (guint) - 1) {
    GST_WARNING_OBJECT (asrc, "couldn't get latency");
    return 0;
  }

  GST_DEBUG_OBJECT (asrc, "got latency: %u", sndiosrc->latency);

  return sndiosrc->latency;
}

static void
gst_sndiosrc_reset (GstAudioSrc * asrc)
{
  /* no way to flush the buffers with sndio ? */

  GST_DEBUG_OBJECT (asrc, "reset called");
}

static void
gst_sndiosrc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSndioSrc *sndiosrc = GST_SNDIOSRC (object);

  switch (prop_id) {
    case PROP_HOST:
      g_free (sndiosrc->host);
      sndiosrc->host = g_value_dup_string (value);
      break;
    default:
      break;
  }
}

static void
gst_sndiosrc_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstSndioSrc *sndiosrc = GST_SNDIOSRC (object);

  switch (prop_id) {
    case PROP_HOST:
      g_value_set_string (value, sndiosrc->host);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
