/*
 * 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-sndiosink
 * @see_also: #GstAutoAudioSink
 *
 * <refsect2>
 * <para>
 * This element outputs sound to a sound card using sndio.
 * </para>
 * <para>
 * Simple example pipeline that plays an Ogg/Vorbis file via sndio:
 * <programlisting>
 * gst-launch-1.0 -v filesrc location=foo.ogg ! decodebin ! audioconvert ! audioresample ! sndiosink
 * </programlisting>
 * </para>
 * </refsect2>
 */

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

#include "sndiosink.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_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    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_sndiosink_finalize (GObject * object);

static GstCaps *gst_sndiosink_getcaps (GstBaseSink * bsink);

static gboolean gst_sndiosink_open (GstAudioSink * asink);
static gboolean gst_sndiosink_close (GstAudioSink * asink);
static gboolean gst_sndiosink_prepare (GstAudioSink * asink,
    GstRingBufferSpec * spec);
static gboolean gst_sndiosink_unprepare (GstAudioSink * asink);
static guint gst_sndiosink_write (GstAudioSink * asink, gpointer data,
    guint length);
static guint gst_sndiosink_delay (GstAudioSink * asink);
static void gst_sndiosink_reset (GstAudioSink * asink);

static void gst_sndiosink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_sndiosink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_sndiosink_cb (void *addr, int delta);

GST_BOILERPLATE (GstSndioSink, gst_sndiosink, GstAudioSink,
    GST_TYPE_AUDIO_SINK);

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

  gst_element_class_set_static_metadata (element_class,
      "Sndio audio sink",
      "Sink/Audio",
      "Plays audio through sndio", "Jacob Meuser <jakemsr@sdf.lonestar.org>");

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

static void
gst_sndiosink_class_init (GstSndioSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstBaseSinkClass *gstbasesink_class;
  GstBaseAudioSinkClass *gstbaseaudiosink_class;
  GstAudioSinkClass *gstaudiosink_class;

  gobject_class = (GObjectClass *) klass;
  gstbasesink_class = (GstBaseSinkClass *) klass;
  gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
  gstaudiosink_class = (GstAudioSinkClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = gst_sndiosink_finalize;

  gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_sndiosink_getcaps);

  gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_sndiosink_open);
  gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_sndiosink_close);
  gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_sndiosink_prepare);
  gstaudiosink_class->unprepare = GST_DEBUG_FUNCPTR (gst_sndiosink_unprepare);
  gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_sndiosink_write);
  gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_sndiosink_delay);
  gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_sndiosink_reset);

  gobject_class->set_property = gst_sndiosink_set_property;
  gobject_class->get_property = gst_sndiosink_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_sndiosink_init (GstSndioSink * sndiosink, GstSndioSinkClass * klass)
{
  sndiosink->hdl = NULL;
  sndiosink->host = g_strdup (g_getenv ("AUDIODEVICE"));
}

static void
gst_sndiosink_finalize (GObject * object)
{
  GstSndioSink *sndiosink = GST_SNDIOSINK (object);

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

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

static GstCaps *
gst_sndiosink_getcaps (GstBaseSink * bsink)
{
  GstSndioSink *sndiosink;

  sndiosink = GST_SNDIOSINK (bsink);

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

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

  return gst_caps_ref (sndiosink->cur_caps);
}

static gboolean
gst_sndiosink_open (GstAudioSink * asink)
{
  GstPadTemplate *pad_template;
  GstSndioSink *sndiosink;
  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;

  sndiosink = GST_SNDIOSINK (asink);

  GST_DEBUG_OBJECT (sndiosink, "open");

  /* conect */
  sndiosink->hdl = sio_open (sndiosink->host, SIO_PLAY, 0);

  if (sndiosink->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 (sndiosink->hdl, &par))
    goto no_server_info;

  if (!sio_getcap (sndiosink->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.pchan & (1 << j)) {
        chan = cap.pchan[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.pchan);
  }

  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_sink_factory);
  sndiosink->cur_caps =
      gst_caps_copy (gst_pad_template_get_caps (pad_template));
  gst_object_unref (pad_template);

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

    s = gst_caps_get_structure (sndiosink->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 (sndiosink, RESOURCE, OPEN_WRITE,
        (_("Could not establish connection to sndio")),
        ("can't open connection to sndio"));
    return FALSE;
  }
no_server_info:
  {
    GST_ELEMENT_ERROR (sndiosink, RESOURCE, OPEN_WRITE,
        (_("Failed to query sndio capabilities")),
        ("couldn't get sndio info!"));
    return FALSE;
  }
}

static gboolean
gst_sndiosink_close (GstAudioSink * asink)
{
  GstSndioSink *sndiosink = GST_SNDIOSINK (asink);

  GST_DEBUG_OBJECT (sndiosink, "close");

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

  return TRUE;
}

static void
gst_sndiosink_cb (void *addr, int delta)
{
  GstSndioSink *sndiosink = GST_SNDIOSINK ((GstAudioSink *) addr);

  sndiosink->realpos += delta;

  if (sndiosink->realpos >= sndiosink->playpos)
    sndiosink->latency = 0;
  else
    sndiosink->latency = sndiosink->playpos - sndiosink->realpos;
}

static gboolean
gst_sndiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
{
  GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
  struct sio_par par;
  int spec_bpf;

  GST_DEBUG_OBJECT (sndiosink, "prepare");

  sndiosink->playpos = sndiosink->realpos = sndiosink->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.pchan = spec->channels;

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

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

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

  sio_getpar (sndiosink->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.pchan;

  sndiosink->bpf = par.bps * par.pchan;

  spec->segsize = par.round * par.pchan * 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 (sndiosink->hdl, gst_sndiosink_cb, sndiosink);

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

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

  return TRUE;

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

static gboolean
gst_sndiosink_unprepare (GstAudioSink * asink)
{
  GstSndioSink *sndiosink = GST_SNDIOSINK (asink);

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

  sio_stop (sndiosink->hdl);

  return TRUE;
}

static guint
gst_sndiosink_write (GstAudioSink * asink, gpointer data, guint length)
{
  GstSndioSink *sndiosink = GST_SNDIOSINK (asink);
  guint done;

  done = sio_write (sndiosink->hdl, data, length);

  if (done == 0)
    goto write_error;

  sndiosink->playpos += (done / sndiosink->bpf);

  data = (char *) data + done;

  return done;

  /* ERRORS */
write_error:
  {
    GST_ELEMENT_ERROR (sndiosink, RESOURCE, WRITE,
        ("Failed to write data to sndio"), GST_ERROR_SYSTEM);
    return 0;
  }
}

static guint
gst_sndiosink_delay (GstAudioSink * asink)
{
  GstSndioSink *sndiosink = GST_SNDIOSINK (asink);

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

  GST_DEBUG_OBJECT (asink, "got latency: %u", sndiosink->latency);

  return sndiosink->latency;
}

static void
gst_sndiosink_reset (GstAudioSink * asink)
{
  /* no way to flush the buffers with sndio ? */

  GST_DEBUG_OBJECT (asink, "reset called");
}

static void
gst_sndiosink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSndioSink *sndiosink = GST_SNDIOSINK (object);

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

static void
gst_sndiosink_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstSndioSink *sndiosink = GST_SNDIOSINK (object);

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