/* GStreamer OSS4 audio source
 * Copyright (C) 2007-2008 Tim-Philipp Müller <tim centricular net>
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:element-oss4src
 *
 * This element lets you record sound using the Open Sound System (OSS)
 * version 4.
 * 
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 -v oss4src ! queue ! audioconvert ! vorbisenc ! oggmux ! filesink location=mymusic.ogg
 * ]| will record sound from your sound card using OSS4 and encode it to an
 * Ogg/Vorbis file (this will only work if your mixer settings are right
 * and the right inputs areenabled etc.)
 * </refsect2>
 *
 * Since: 0.10.7
 */

/* FIXME: make sure we're not doing ioctls from the app thread (e.g. via the
 * mixer interface) while recording */

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

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

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

#define NO_LEGACY_MIXER
#include "oss4-audio.h"
#include "oss4-source.h"
#include "oss4-property-probe.h"
#include "oss4-soundcard.h"

#define GST_OSS4_SOURCE_IS_OPEN(src)  (GST_OSS4_SOURCE(src)->fd != -1)

GST_DEBUG_CATEGORY_EXTERN (oss4src_debug);
#define GST_CAT_DEFAULT oss4src_debug

#define DEFAULT_DEVICE       NULL
#define DEFAULT_DEVICE_NAME  NULL

enum
{
  PROP_0,
  PROP_DEVICE,
  PROP_DEVICE_NAME
};

#define gst_oss4_source_parent_class parent_class
G_DEFINE_TYPE (GstOss4Source, gst_oss4_source, GST_TYPE_AUDIO_SRC);

static void gst_oss4_source_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_oss4_source_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);

static void gst_oss4_source_dispose (GObject * object);
static void gst_oss4_source_finalize (GstOss4Source * osssrc);

static GstCaps *gst_oss4_source_getcaps (GstBaseSrc * bsrc, GstCaps * filter);

static gboolean gst_oss4_source_open (GstAudioSrc * asrc,
    gboolean silent_errors);
static gboolean gst_oss4_source_open_func (GstAudioSrc * asrc);
static gboolean gst_oss4_source_close (GstAudioSrc * asrc);
static gboolean gst_oss4_source_prepare (GstAudioSrc * asrc,
    GstAudioRingBufferSpec * spec);
static gboolean gst_oss4_source_unprepare (GstAudioSrc * asrc);
static guint gst_oss4_source_read (GstAudioSrc * asrc, gpointer data,
    guint length, GstClockTime * timestamp);
static guint gst_oss4_source_delay (GstAudioSrc * asrc);
static void gst_oss4_source_reset (GstAudioSrc * asrc);

static void
gst_oss4_source_class_init (GstOss4SourceClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSrcClass *gstbasesrc_class;
  GstAudioSrcClass *gstaudiosrc_class;
  GstPadTemplate *templ;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasesrc_class = (GstBaseSrcClass *) klass;
  gstaudiosrc_class = (GstAudioSrcClass *) klass;

  gobject_class->dispose = gst_oss4_source_dispose;
  gobject_class->finalize = (GObjectFinalizeFunc) gst_oss4_source_finalize;
  gobject_class->get_property = gst_oss4_source_get_property;
  gobject_class->set_property = gst_oss4_source_set_property;

  gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_oss4_source_getcaps);

  gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_oss4_source_open_func);
  gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_oss4_source_prepare);
  gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_oss4_source_unprepare);
  gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_oss4_source_close);
  gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_oss4_source_read);
  gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_oss4_source_delay);
  gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_oss4_source_reset);

  g_object_class_install_property (gobject_class, PROP_DEVICE,
      g_param_spec_string ("device", "Device",
          "OSS4 device (e.g. /dev/oss/hdaudio0/pcm0 or /dev/dspN) "
          "(NULL = use first available device)",
          DEFAULT_DEVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
      g_param_spec_string ("device-name", "Device name",
          "Human-readable name of the sound device", DEFAULT_DEVICE_NAME,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_static_metadata (gstelement_class,
      "OSS v4 Audio Source", "Source/Audio",
      "Capture from a sound card via OSS version 4",
      "Tim-Philipp Müller <tim centricular net>");

  templ = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
      gst_oss4_audio_get_template_caps ());
  gst_element_class_add_pad_template (gstelement_class, templ);
}

static void
gst_oss4_source_init (GstOss4Source * osssrc)
{
  const gchar *device;

  device = g_getenv ("AUDIODEV");
  if (device == NULL)
    device = DEFAULT_DEVICE;

  osssrc->fd = -1;
  osssrc->device = g_strdup (device);
  osssrc->device_name = g_strdup (DEFAULT_DEVICE_NAME);
  osssrc->device_name = NULL;
}

static void
gst_oss4_source_finalize (GstOss4Source * oss)
{
  g_free (oss->device);
  oss->device = NULL;

  G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (oss));
}

static void
gst_oss4_source_dispose (GObject * object)
{
  GstOss4Source *oss = GST_OSS4_SOURCE (object);

  if (oss->probed_caps) {
    gst_caps_unref (oss->probed_caps);
    oss->probed_caps = NULL;
  }

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

static void
gst_oss4_source_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstOss4Source *oss;

  oss = GST_OSS4_SOURCE (object);

  switch (prop_id) {
    case PROP_DEVICE:
      GST_OBJECT_LOCK (oss);
      if (oss->fd == -1) {
        g_free (oss->device);
        oss->device = g_value_dup_string (value);
        g_free (oss->device_name);
        oss->device_name = NULL;
      } else {
        g_warning ("%s: can't change \"device\" property while audio source "
            "is open", GST_OBJECT_NAME (oss));
      }
      GST_OBJECT_UNLOCK (oss);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_oss4_source_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstOss4Source *oss;

  oss = GST_OSS4_SOURCE (object);

  switch (prop_id) {
    case PROP_DEVICE:
      GST_OBJECT_LOCK (oss);
      g_value_set_string (value, oss->device);
      GST_OBJECT_UNLOCK (oss);
      break;
    case PROP_DEVICE_NAME:
      GST_OBJECT_LOCK (oss);
      /* If device is set, try to retrieve the name even if we're not open */
      if (oss->fd == -1 && oss->device != NULL) {
        if (gst_oss4_source_open (GST_AUDIO_SRC (oss), TRUE)) {
          g_value_set_string (value, oss->device_name);
          gst_oss4_source_close (GST_AUDIO_SRC (oss));
        } else {
          gchar *name = NULL;

          gst_oss4_property_probe_find_device_name_nofd (GST_OBJECT (oss),
              oss->device, &name);
          g_value_set_string (value, name);
          g_free (name);
        }
      } else {
        g_value_set_string (value, oss->device_name);
      }

      GST_OBJECT_UNLOCK (oss);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstCaps *
gst_oss4_source_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
{
  GstOss4Source *oss;
  GstCaps *caps;

  oss = GST_OSS4_SOURCE (bsrc);

  if (oss->fd == -1) {
    caps = gst_oss4_audio_get_template_caps ();
  } else if (oss->probed_caps) {
    caps = gst_caps_copy (oss->probed_caps);
  } else {
    caps = gst_oss4_audio_probe_caps (GST_OBJECT (oss), oss->fd);
    if (caps != NULL && !gst_caps_is_empty (caps)) {
      oss->probed_caps = gst_caps_copy (caps);
    }
  }

  if (filter && caps) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (caps);
    return intersection;
  } else {
    return caps;
  }
}

/* note: we must not take the object lock here unless we fix up get_property */
static gboolean
gst_oss4_source_open (GstAudioSrc * asrc, gboolean silent_errors)
{
  GstOss4Source *oss;
  gchar *device;
  int mode;

  oss = GST_OSS4_SOURCE (asrc);

  if (oss->device)
    device = g_strdup (oss->device);
  else
    device = gst_oss4_audio_find_device (GST_OBJECT_CAST (oss));

  /* desperate times, desperate measures */
  if (device == NULL)
    device = g_strdup ("/dev/dsp0");

  GST_INFO_OBJECT (oss, "Trying to open OSS4 device '%s'", device);

  /* we open in non-blocking mode even if we don't really want to do writes
   * non-blocking because we can't be sure that this is really a genuine
   * OSS4 device with well-behaved drivers etc. We really don't want to
   * hang forever under any circumstances. */
  oss->fd = open (device, O_RDONLY | O_NONBLOCK, 0);
  if (oss->fd == -1) {
    switch (errno) {
      case EBUSY:
        goto busy;
      case EACCES:
        goto no_permission;
      default:
        goto open_failed;
    }
  }

  GST_INFO_OBJECT (oss, "Opened device");

  /* Make sure it's OSS4. If it's old OSS, let osssink handle it */
  if (!gst_oss4_audio_check_version (GST_OBJECT_CAST (oss), oss->fd))
    goto legacy_oss;

  /* now remove the non-blocking flag. */
  mode = fcntl (oss->fd, F_GETFL);
  mode &= ~O_NONBLOCK;
  if (fcntl (oss->fd, F_SETFL, mode) < 0) {
    /* some drivers do no support unsetting the non-blocking flag, try to
     * close/open the device then. This is racy but we error out properly. */
    GST_WARNING_OBJECT (oss, "failed to unset O_NONBLOCK (buggy driver?), "
        "will try to re-open device now");
    gst_oss4_source_close (asrc);
    if ((oss->fd = open (device, O_RDONLY, 0)) == -1)
      goto non_block;
  }

  oss->open_device = device;

  /* not using ENGINEINFO here because it sometimes returns a different and
   * less useful name than AUDIOINFO for the same device */
  if (!gst_oss4_property_probe_find_device_name (GST_OBJECT (oss), oss->fd,
          oss->open_device, &oss->device_name)) {
    oss->device_name = NULL;
  }

  return TRUE;

  /* ERRORS */
busy:
  {
    if (!silent_errors) {
      GST_ELEMENT_ERROR (oss, RESOURCE, BUSY,
          (_("Could not open audio device for playback. "
                  "Device is being used by another application.")), (NULL));
    }
    g_free (device);
    return FALSE;
  }
no_permission:
  {
    if (!silent_errors) {
      GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ,
          (_("Could not open audio device for playback. "
                  "You don't have permission to open the device.")),
          GST_ERROR_SYSTEM);
    }
    g_free (device);
    return FALSE;
  }
open_failed:
  {
    if (!silent_errors) {
      GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ,
          (_("Could not open audio device for playback.")), GST_ERROR_SYSTEM);
    }
    g_free (device);
    return FALSE;
  }
legacy_oss:
  {
    gst_oss4_source_close (asrc);
    if (!silent_errors) {
      GST_ELEMENT_ERROR (oss, RESOURCE, OPEN_READ,
          (_("Could not open audio device for playback. "
                  "This version of the Open Sound System is not supported by this "
                  "element.")), ("Try the 'osssink' element instead"));
    }
    g_free (device);
    return FALSE;
  }
non_block:
  {
    if (!silent_errors) {
      GST_ELEMENT_ERROR (oss, RESOURCE, SETTINGS, (NULL),
          ("Unable to set device %s into non-blocking mode: %s",
              oss->device, g_strerror (errno)));
    }
    g_free (device);
    return FALSE;
  }
}

static gboolean
gst_oss4_source_open_func (GstAudioSrc * asrc)
{
  return gst_oss4_source_open (asrc, FALSE);
}

static gboolean
gst_oss4_source_close (GstAudioSrc * asrc)
{
  GstOss4Source *oss;

  oss = GST_OSS4_SOURCE (asrc);

  if (oss->fd != -1) {
    GST_DEBUG_OBJECT (oss, "closing device");
    close (oss->fd);
    oss->fd = -1;
  }

  oss->bytes_per_sample = 0;

  gst_caps_replace (&oss->probed_caps, NULL);

  g_free (oss->open_device);
  oss->open_device = NULL;

  g_free (oss->device_name);
  oss->device_name = NULL;

  return TRUE;
}

static gboolean
gst_oss4_source_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
{
  GstOss4Source *oss;

  oss = GST_OSS4_SOURCE (asrc);

  if (!gst_oss4_audio_set_format (GST_OBJECT_CAST (oss), oss->fd, spec)) {
    GST_WARNING_OBJECT (oss, "Couldn't set requested format %" GST_PTR_FORMAT,
        spec->caps);
    return FALSE;
  }

  oss->bytes_per_sample = GST_AUDIO_INFO_BPF (&spec->info);

  return TRUE;
}

static gboolean
gst_oss4_source_unprepare (GstAudioSrc * asrc)
{
  /* could do a SNDCTL_DSP_HALT, but the OSS manual recommends a close/open,
   * since HALT won't properly reset some devices, apparently */

  if (!gst_oss4_source_close (asrc))
    goto couldnt_close;

  if (!gst_oss4_source_open_func (asrc))
    goto couldnt_reopen;

  return TRUE;

  /* ERRORS */
couldnt_close:
  {
    GST_DEBUG_OBJECT (asrc, "Couldn't close the audio device");
    return FALSE;
  }
couldnt_reopen:
  {
    GST_DEBUG_OBJECT (asrc, "Couldn't reopen the audio device");
    return FALSE;
  }
}

static guint
gst_oss4_source_read (GstAudioSrc * asrc, gpointer data, guint length,
    GstClockTime * timestamp)
{
  GstOss4Source *oss;
  int n;

  oss = GST_OSS4_SOURCE_CAST (asrc);

  n = read (oss->fd, data, length);
  GST_LOG_OBJECT (asrc, "%u bytes, %u samples", n, n / oss->bytes_per_sample);

  if (G_UNLIKELY (n < 0)) {
    switch (errno) {
      case ENOTSUP:
      case EACCES:{
        /* This is the most likely cause, I think */
        GST_ELEMENT_ERROR (asrc, RESOURCE, READ,
            (_("Recording is not supported by this audio device.")),
            ("read: %s (device: %s) (maybe this is an output-only device?)",
                g_strerror (errno), oss->open_device));
        break;
      }
      default:{
        GST_ELEMENT_ERROR (asrc, RESOURCE, READ,
            (_("Error recording from audio device.")),
            ("read: %s (device: %s)", g_strerror (errno), oss->open_device));
        break;
      }
    }
  }

  return (guint) n;
}

static guint
gst_oss4_source_delay (GstAudioSrc * asrc)
{
  audio_buf_info info = { 0, };
  GstOss4Source *oss;
  guint delay;

  oss = GST_OSS4_SOURCE_CAST (asrc);

  if (ioctl (oss->fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
    GST_LOG_OBJECT (oss, "GETISPACE failed: %s", g_strerror (errno));
    return 0;
  }

  delay = (info.fragstotal * info.fragsize) - info.bytes;
  GST_LOG_OBJECT (oss, "fragstotal:%d, fragsize:%d, bytes:%d, delay:%d",
      info.fragstotal, info.fragsize, info.bytes, delay);
  return delay;
}

static void
gst_oss4_source_reset (GstAudioSrc * asrc)
{
  /* There's nothing we can do here really: OSS can't handle access to the
   * same device/fd from multiple threads and might deadlock or blow up in
   * other ways if we try an ioctl SNDCTL_DSP_HALT or similar */
}
