/*
 * 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_static_pad_template (element_class,
      &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;
  }
}
