/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/sound/alsasoundsystem.h"

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

namespace rtc {

// Lookup table from the rtc 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.
    rtc::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 * rtc::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 rtc::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_;
  rtc::scoped_ptr<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 rtc::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 &&
        !rtc::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 = rtc::kNumMicrosecsPerSec *
        params.latency /
        params.freq /
        FrameSize(params);
    // And this is what we'll actually use.
    latency = rtc::_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 / rtc::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 rtc
