/*
 * libjingle
 * Copyright 2004--2010, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/sound/alsasoundsystem.h"

#include "talk/base/common.h"
#include "talk/base/logging.h"
#include "talk/base/scoped_ptr.h"
#include "talk/base/stringutils.h"
#include "talk/base/timeutils.h"
#include "talk/base/worker.h"
#include "talk/sound/sounddevicelocator.h"
#include "talk/sound/soundinputstreaminterface.h"
#include "talk/sound/soundoutputstreaminterface.h"

namespace cricket {

// Lookup table from the cricket format enum in soundsysteminterface.h to
// ALSA's enums.
static const snd_pcm_format_t kCricketFormatToAlsaFormatTable[] = {
  // The order here must match the order in soundsysteminterface.h
  SND_PCM_FORMAT_S16_LE,
};

// Lookup table for the size of a single sample of a given format.
static const size_t kCricketFormatToSampleSizeTable[] = {
  // The order here must match the order in soundsysteminterface.h
  sizeof(int16_t),  // 2
};

// Minimum latency we allow, in microseconds. This is more or less arbitrary,
// but it has to be at least large enough to be able to buffer data during a
// missed context switch, and the typical Linux scheduling quantum is 10ms.
static const int kMinimumLatencyUsecs = 20 * 1000;

// The latency we'll use for kNoLatencyRequirements (chosen arbitrarily).
static const int kDefaultLatencyUsecs = kMinimumLatencyUsecs * 2;

// We translate newlines in ALSA device descriptions to hyphens.
static const char kAlsaDescriptionSearch[] = "\n";
static const char kAlsaDescriptionReplace[] = " - ";

class AlsaDeviceLocator : public SoundDeviceLocator {
 public:
  AlsaDeviceLocator(const std::string &name,
                    const std::string &device_name)
      : SoundDeviceLocator(name, device_name) {
    // The ALSA descriptions have newlines in them, which won't show up in
    // a drop-down box. Replace them with hyphens.
    talk_base::replace_substrs(kAlsaDescriptionSearch,
                               sizeof(kAlsaDescriptionSearch) - 1,
                               kAlsaDescriptionReplace,
                               sizeof(kAlsaDescriptionReplace) - 1,
                               &name_);
  }

  virtual SoundDeviceLocator *Copy() const {
    return new AlsaDeviceLocator(*this);
  }
};

// Functionality that is common to both AlsaInputStream and AlsaOutputStream.
class AlsaStream {
 public:
  AlsaStream(AlsaSoundSystem *alsa,
             snd_pcm_t *handle,
             size_t frame_size,
             int wait_timeout_ms,
             int flags,
             int freq)
      : alsa_(alsa),
        handle_(handle),
        frame_size_(frame_size),
        wait_timeout_ms_(wait_timeout_ms),
        flags_(flags),
        freq_(freq) {
  }

  ~AlsaStream() {
    Close();
  }

  // Waits for the stream to be ready to accept/return more data, and returns
  // how much can be written/read, or 0 if we need to Wait() again.
  snd_pcm_uframes_t Wait() {
    snd_pcm_sframes_t frames;
    // Ideally we would not use snd_pcm_wait() and instead hook snd_pcm_poll_*
    // into PhysicalSocketServer, but PhysicalSocketServer is nasty enough
    // already and the current clients of SoundSystemInterface do not run
    // anything else on their worker threads, so snd_pcm_wait() is good enough.
    frames = symbol_table()->snd_pcm_avail_update()(handle_);
    if (frames < 0) {
      LOG(LS_ERROR) << "snd_pcm_avail_update(): " << GetError(frames);
      Recover(frames);
      return 0;
    } else if (frames > 0) {
      // Already ready, so no need to wait.
      return frames;
    }
    // Else no space/data available, so must wait.
    int ready = symbol_table()->snd_pcm_wait()(handle_, wait_timeout_ms_);
    if (ready < 0) {
      LOG(LS_ERROR) << "snd_pcm_wait(): " << GetError(ready);
      Recover(ready);
      return 0;
    } else if (ready == 0) {
      // Timeout, so nothing can be written/read right now.
      // We set the timeout to twice the requested latency, so continuous
      // timeouts are indicative of a problem, so log as a warning.
      LOG(LS_WARNING) << "Timeout while waiting on stream";
      return 0;
    }
    // Else ready > 0 (i.e., 1), so it's ready. Get count.
    frames = symbol_table()->snd_pcm_avail_update()(handle_);
    if (frames < 0) {
      LOG(LS_ERROR) << "snd_pcm_avail_update(): " << GetError(frames);
      Recover(frames);
      return 0;
    } else if (frames == 0) {
      // wait() said we were ready, so this ought to have been positive. Has
      // been observed to happen in practice though.
      LOG(LS_WARNING) << "Spurious wake-up";
    }
    return frames;
  }

  int CurrentDelayUsecs() {
    if (!(flags_ & SoundSystemInterface::FLAG_REPORT_LATENCY)) {
      return 0;
    }

    snd_pcm_sframes_t delay;
    int err = symbol_table()->snd_pcm_delay()(handle_, &delay);
    if (err != 0) {
      LOG(LS_ERROR) << "snd_pcm_delay(): " << GetError(err);
      Recover(err);
      // We'd rather continue playout/capture with an incorrect delay than stop
      // it altogether, so return a valid value.
      return 0;
    }
    // The delay is in frames. Convert to microseconds.
    return delay * talk_base::kNumMicrosecsPerSec / freq_;
  }

  // Used to recover from certain recoverable errors, principally buffer overrun
  // or underrun (identified as EPIPE). Without calling this the stream stays
  // in the error state forever.
  bool Recover(int error) {
    int err;
    err = symbol_table()->snd_pcm_recover()(
        handle_,
        error,
        // Silent; i.e., no logging on stderr.
        1);
    if (err != 0) {
      // Docs say snd_pcm_recover returns the original error if it is not one
      // of the recoverable ones, so this log message will probably contain the
      // same error twice.
      LOG(LS_ERROR) << "Unable to recover from \"" << GetError(error) << "\": "
                    << GetError(err);
      return false;
    }
    if (error == -EPIPE &&  // Buffer underrun/overrun.
        symbol_table()->snd_pcm_stream()(handle_) == SND_PCM_STREAM_CAPTURE) {
      // For capture streams we also have to repeat the explicit start() to get
      // data flowing again.
      err = symbol_table()->snd_pcm_start()(handle_);
      if (err != 0) {
        LOG(LS_ERROR) << "snd_pcm_start(): " << GetError(err);
        return false;
      }
    }
    return true;
  }

  bool Close() {
    if (handle_) {
      int err;
      err = symbol_table()->snd_pcm_drop()(handle_);
      if (err != 0) {
        LOG(LS_ERROR) << "snd_pcm_drop(): " << GetError(err);
        // Continue anyways.
      }
      err = symbol_table()->snd_pcm_close()(handle_);
      if (err != 0) {
        LOG(LS_ERROR) << "snd_pcm_close(): " << GetError(err);
        // Continue anyways.
      }
      handle_ = NULL;
    }
    return true;
  }

  AlsaSymbolTable *symbol_table() {
    return &alsa_->symbol_table_;
  }

  snd_pcm_t *handle() {
    return handle_;
  }

  const char *GetError(int err) {
    return alsa_->GetError(err);
  }

  size_t frame_size() {
    return frame_size_;
  }

 private:
  AlsaSoundSystem *alsa_;
  snd_pcm_t *handle_;
  size_t frame_size_;
  int wait_timeout_ms_;
  int flags_;
  int freq_;

  DISALLOW_COPY_AND_ASSIGN(AlsaStream);
};

// Implementation of an input stream. See soundinputstreaminterface.h regarding
// thread-safety.
class AlsaInputStream :
    public SoundInputStreamInterface,
    private talk_base::Worker {
 public:
  AlsaInputStream(AlsaSoundSystem *alsa,
                  snd_pcm_t *handle,
                  size_t frame_size,
                  int wait_timeout_ms,
                  int flags,
                  int freq)
      : stream_(alsa, handle, frame_size, wait_timeout_ms, flags, freq),
        buffer_size_(0) {
  }

  virtual ~AlsaInputStream() {
    bool success = StopReading();
    // We need that to live.
    VERIFY(success);
  }

  virtual bool StartReading() {
    return StartWork();
  }

  virtual bool StopReading() {
    return StopWork();
  }

  virtual bool GetVolume(int *volume) {
    // TODO: Implement this.
    return false;
  }

  virtual bool SetVolume(int volume) {
    // TODO: Implement this.
    return false;
  }

  virtual bool Close() {
    return StopReading() && stream_.Close();
  }

  virtual int LatencyUsecs() {
    return stream_.CurrentDelayUsecs();
  }

 private:
  // Inherited from Worker.
  virtual void OnStart() {
    HaveWork();
  }

  // Inherited from Worker.
  virtual void OnHaveWork() {
    // Block waiting for data.
    snd_pcm_uframes_t avail = stream_.Wait();
    if (avail > 0) {
      // Data is available.
      size_t size = avail * stream_.frame_size();
      if (size > buffer_size_) {
        // Must increase buffer size.
        buffer_.reset(new char[size]);
        buffer_size_ = size;
      }
      // Read all the data.
      snd_pcm_sframes_t read = stream_.symbol_table()->snd_pcm_readi()(
          stream_.handle(),
          buffer_.get(),
          avail);
      if (read < 0) {
        LOG(LS_ERROR) << "snd_pcm_readi(): " << GetError(read);
        stream_.Recover(read);
      } else if (read == 0) {
        // Docs say this shouldn't happen.
        ASSERT(false);
        LOG(LS_ERROR) << "No data?";
      } else {
        // Got data. Pass it off to the app.
        SignalSamplesRead(buffer_.get(),
                          read * stream_.frame_size(),
                          this);
      }
    }
    // Check for more data with no delay, after any pending messages are
    // dispatched.
    HaveWork();
  }

  // Inherited from Worker.
  virtual void OnStop() {
    // Nothing to do.
  }

  const char *GetError(int err) {
    return stream_.GetError(err);
  }

  AlsaStream stream_;
  talk_base::scoped_array<char> buffer_;
  size_t buffer_size_;

  DISALLOW_COPY_AND_ASSIGN(AlsaInputStream);
};

// Implementation of an output stream. See soundoutputstreaminterface.h
// regarding thread-safety.
class AlsaOutputStream :
    public SoundOutputStreamInterface,
    private talk_base::Worker {
 public:
  AlsaOutputStream(AlsaSoundSystem *alsa,
                   snd_pcm_t *handle,
                   size_t frame_size,
                   int wait_timeout_ms,
                   int flags,
                   int freq)
      : stream_(alsa, handle, frame_size, wait_timeout_ms, flags, freq) {
  }

  virtual ~AlsaOutputStream() {
    bool success = DisableBufferMonitoring();
    // We need that to live.
    VERIFY(success);
  }

  virtual bool EnableBufferMonitoring() {
    return StartWork();
  }

  virtual bool DisableBufferMonitoring() {
    return StopWork();
  }

  virtual bool WriteSamples(const void *sample_data,
                            size_t size) {
    if (size % stream_.frame_size() != 0) {
      // No client of SoundSystemInterface does this, so let's not support it.
      // (If we wanted to support it, we'd basically just buffer the fractional
      // frame until we get more data.)
      ASSERT(false);
      LOG(LS_ERROR) << "Writes with fractional frames are not supported";
      return false;
    }
    snd_pcm_uframes_t frames = size / stream_.frame_size();
    snd_pcm_sframes_t written = stream_.symbol_table()->snd_pcm_writei()(
        stream_.handle(),
        sample_data,
        frames);
    if (written < 0) {
      LOG(LS_ERROR) << "snd_pcm_writei(): " << GetError(written);
      stream_.Recover(written);
      return false;
    } else if (static_cast<snd_pcm_uframes_t>(written) < frames) {
      // Shouldn't happen. Drop the rest of the data.
      LOG(LS_ERROR) << "Stream wrote only " << written << " of " << frames
                    << " frames!";
      return false;
    }
    return true;
  }

  virtual bool GetVolume(int *volume) {
    // TODO: Implement this.
    return false;
  }

  virtual bool SetVolume(int volume) {
    // TODO: Implement this.
    return false;
  }

  virtual bool Close() {
    return DisableBufferMonitoring() && stream_.Close();
  }

  virtual int LatencyUsecs() {
    return stream_.CurrentDelayUsecs();
  }

 private:
  // Inherited from Worker.
  virtual void OnStart() {
    HaveWork();
  }

  // Inherited from Worker.
  virtual void OnHaveWork() {
    snd_pcm_uframes_t avail = stream_.Wait();
    if (avail > 0) {
      size_t space = avail * stream_.frame_size();
      SignalBufferSpace(space, this);
    }
    HaveWork();
  }

  // Inherited from Worker.
  virtual void OnStop() {
    // Nothing to do.
  }

  const char *GetError(int err) {
    return stream_.GetError(err);
  }

  AlsaStream stream_;

  DISALLOW_COPY_AND_ASSIGN(AlsaOutputStream);
};

AlsaSoundSystem::AlsaSoundSystem() : initialized_(false) {}

AlsaSoundSystem::~AlsaSoundSystem() {
  // Not really necessary, because Terminate() doesn't really do anything.
  Terminate();
}

bool AlsaSoundSystem::Init() {
  if (IsInitialized()) {
    return true;
  }

  // Load libasound.
  if (!symbol_table_.Load()) {
    // Very odd for a Linux machine to not have a working libasound ...
    LOG(LS_ERROR) << "Failed to load symbol table";
    return false;
  }

  initialized_ = true;

  return true;
}

void AlsaSoundSystem::Terminate() {
  if (!IsInitialized()) {
    return;
  }

  initialized_ = false;

  // We do not unload the symbol table because we may need it again soon if
  // Init() is called again.
}

bool AlsaSoundSystem::EnumeratePlaybackDevices(
    SoundDeviceLocatorList *devices) {
  return EnumerateDevices(devices, false);
}

bool AlsaSoundSystem::EnumerateCaptureDevices(
    SoundDeviceLocatorList *devices) {
  return EnumerateDevices(devices, true);
}

bool AlsaSoundSystem::GetDefaultPlaybackDevice(SoundDeviceLocator **device) {
  return GetDefaultDevice(device);
}

bool AlsaSoundSystem::GetDefaultCaptureDevice(SoundDeviceLocator **device) {
  return GetDefaultDevice(device);
}

SoundOutputStreamInterface *AlsaSoundSystem::OpenPlaybackDevice(
    const SoundDeviceLocator *device,
    const OpenParams &params) {
  return OpenDevice<SoundOutputStreamInterface>(
      device,
      params,
      SND_PCM_STREAM_PLAYBACK,
      &AlsaSoundSystem::StartOutputStream);
}

SoundInputStreamInterface *AlsaSoundSystem::OpenCaptureDevice(
    const SoundDeviceLocator *device,
    const OpenParams &params) {
  return OpenDevice<SoundInputStreamInterface>(
      device,
      params,
      SND_PCM_STREAM_CAPTURE,
      &AlsaSoundSystem::StartInputStream);
}

const char *AlsaSoundSystem::GetName() const {
  return "ALSA";
}

bool AlsaSoundSystem::EnumerateDevices(
    SoundDeviceLocatorList *devices,
    bool capture_not_playback) {
  ClearSoundDeviceLocatorList(devices);

  if (!IsInitialized()) {
    return false;
  }

  const char *type = capture_not_playback ? "Input" : "Output";
  // dmix and dsnoop are only for playback and capture, respectively, but ALSA
  // stupidly includes them in both lists.
  const char *ignore_prefix = capture_not_playback ? "dmix:" : "dsnoop:";
  // (ALSA lists many more "devices" of questionable interest, but we show them
  // just in case the weird devices may actually be desirable for some
  // users/systems.)
  const char *ignore_default = "default";
  const char *ignore_null = "null";
  const char *ignore_pulse = "pulse";
  // The 'pulse' entry has a habit of mysteriously disappearing when you query
  // a second time. Remove it from our list. (GIPS lib did the same thing.)
  int err;

  void **hints;
  err = symbol_table_.snd_device_name_hint()(-1,     // All cards
                                             "pcm",  // Only PCM devices
                                             &hints);
  if (err != 0) {
    LOG(LS_ERROR) << "snd_device_name_hint(): " << GetError(err);
    return false;
  }

  for (void **list = hints; *list != NULL; ++list) {
    char *actual_type = symbol_table_.snd_device_name_get_hint()(*list, "IOID");
    if (actual_type) {  // NULL means it's both.
      bool wrong_type = (strcmp(actual_type, type) != 0);
      free(actual_type);
      if (wrong_type) {
        // Wrong type of device (i.e., input vs. output).
        continue;
      }
    }

    char *name = symbol_table_.snd_device_name_get_hint()(*list, "NAME");
    if (!name) {
      LOG(LS_ERROR) << "Device has no name???";
      // Skip it.
      continue;
    }

    // Now check if we actually want to show this device.
    if (strcmp(name, ignore_default) != 0 &&
        strcmp(name, ignore_null) != 0 &&
        strcmp(name, ignore_pulse) != 0 &&
        !talk_base::starts_with(name, ignore_prefix)) {

      // Yes, we do.
      char *desc = symbol_table_.snd_device_name_get_hint()(*list, "DESC");
      if (!desc) {
        // Virtual devices don't necessarily have descriptions. Use their names
        // instead (not pretty!).
        desc = name;
      }

      AlsaDeviceLocator *device = new AlsaDeviceLocator(desc, name);

      devices->push_back(device);

      if (desc != name) {
        free(desc);
      }
    }

    free(name);
  }

  err = symbol_table_.snd_device_name_free_hint()(hints);
  if (err != 0) {
    LOG(LS_ERROR) << "snd_device_name_free_hint(): " << GetError(err);
    // Continue and return true anyways, since we did get the whole list.
  }

  return true;
}

bool AlsaSoundSystem::GetDefaultDevice(SoundDeviceLocator **device) {
  if (!IsInitialized()) {
    return false;
  }
  *device = new AlsaDeviceLocator("Default device", "default");
  return true;
}

inline size_t AlsaSoundSystem::FrameSize(const OpenParams &params) {
  ASSERT(static_cast<int>(params.format) <
         ARRAY_SIZE(kCricketFormatToSampleSizeTable));
  return kCricketFormatToSampleSizeTable[params.format] * params.channels;
}

template <typename StreamInterface>
StreamInterface *AlsaSoundSystem::OpenDevice(
    const SoundDeviceLocator *device,
    const OpenParams &params,
    snd_pcm_stream_t type,
    StreamInterface *(AlsaSoundSystem::*start_fn)(
        snd_pcm_t *handle,
        size_t frame_size,
        int wait_timeout_ms,
        int flags,
        int freq)) {

  if (!IsInitialized()) {
    return NULL;
  }

  StreamInterface *stream;
  int err;

  const char *dev = static_cast<const AlsaDeviceLocator *>(device)->
      device_name().c_str();

  snd_pcm_t *handle = NULL;
  err = symbol_table_.snd_pcm_open()(
      &handle,
      dev,
      type,
      // No flags.
      0);
  if (err != 0) {
    LOG(LS_ERROR) << "snd_pcm_open(" << dev << "): " << GetError(err);
    return NULL;
  }
  LOG(LS_VERBOSE) << "Opening " << dev;
  ASSERT(handle);  // If open succeeded, handle ought to be valid

  // Compute requested latency in microseconds.
  int latency;
  if (params.latency == kNoLatencyRequirements) {
    latency = kDefaultLatencyUsecs;
  } else {
    // kLowLatency is 0, so we treat it the same as a request for zero latency.
    // Compute what the user asked for.
    latency = talk_base::kNumMicrosecsPerSec *
        params.latency /
        params.freq /
        FrameSize(params);
    // And this is what we'll actually use.
    latency = talk_base::_max(latency, kMinimumLatencyUsecs);
  }

  ASSERT(static_cast<int>(params.format) <
         ARRAY_SIZE(kCricketFormatToAlsaFormatTable));

  err = symbol_table_.snd_pcm_set_params()(
      handle,
      kCricketFormatToAlsaFormatTable[params.format],
      // SoundSystemInterface only supports interleaved audio.
      SND_PCM_ACCESS_RW_INTERLEAVED,
      params.channels,
      params.freq,
      1,  // Allow ALSA to resample.
      latency);
  if (err != 0) {
    LOG(LS_ERROR) << "snd_pcm_set_params(): " << GetError(err);
    goto fail;
  }

  err = symbol_table_.snd_pcm_prepare()(handle);
  if (err != 0) {
    LOG(LS_ERROR) << "snd_pcm_prepare(): " << GetError(err);
    goto fail;
  }

  stream = (this->*start_fn)(
      handle,
      FrameSize(params),
      // We set the wait time to twice the requested latency, so that wait
      // timeouts should be rare.
      2 * latency / talk_base::kNumMicrosecsPerMillisec,
      params.flags,
      params.freq);
  if (stream) {
    return stream;
  }
  // Else fall through.

 fail:
  err = symbol_table_.snd_pcm_close()(handle);
  if (err != 0) {
    LOG(LS_ERROR) << "snd_pcm_close(): " << GetError(err);
  }
  return NULL;
}

SoundOutputStreamInterface *AlsaSoundSystem::StartOutputStream(
    snd_pcm_t *handle,
    size_t frame_size,
    int wait_timeout_ms,
    int flags,
    int freq) {
  // Nothing to do here but instantiate the stream.
  return new AlsaOutputStream(
      this, handle, frame_size, wait_timeout_ms, flags, freq);
}

SoundInputStreamInterface *AlsaSoundSystem::StartInputStream(
    snd_pcm_t *handle,
    size_t frame_size,
    int wait_timeout_ms,
    int flags,
    int freq) {
  // Output streams start automatically once enough data has been written, but
  // input streams must be started manually or else snd_pcm_wait() will never
  // return true.
  int err;
  err = symbol_table_.snd_pcm_start()(handle);
  if (err != 0) {
    LOG(LS_ERROR) << "snd_pcm_start(): " << GetError(err);
    return NULL;
  }
  return new AlsaInputStream(
      this, handle, frame_size, wait_timeout_ms, flags, freq);
}

inline const char *AlsaSoundSystem::GetError(int err) {
  return symbol_table_.snd_strerror()(err);
}

}  // namespace cricket
