// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/alsa/alsa_util.h"

#include <alsa/asoundlib.h>

#include "starboard/log.h"

#define ALSA_CHECK(error, alsa_function, failure_return)      \
  do {                                                        \
    if (error < 0) {                                          \
      SB_LOG(ERROR) << __FUNCTION__ << ": " << #alsa_function \
                    << "() failed with error "                \
                    << snd_strerror(error)                    \
                    << " (" << error << ")";                  \
      return (failure_return);                                \
    }                                                         \
  } while (false)

namespace starboard {
namespace shared {
namespace alsa {

namespace {

const snd_pcm_uframes_t kSilenceThresholdInFrames = 256U;
const snd_pcm_uframes_t kStartThresholdInFrames = 1024U;

template <typename T, typename CloseFunc>
class AutoClose {
 public:
  explicit AutoClose(CloseFunc close_func)
      : valid_(false), value_(NULL), close_func_(close_func) {}
  ~AutoClose() {
    if (valid_) {
      close_func_(value_);
    }
  }
  operator T() {
    SB_DCHECK(valid_);
    return value_;
  }
  T* operator&() {
    SB_DCHECK(!valid_);
    return &value_;
  }
  bool is_valid() const { return valid_; }
  void set_valid() {
    SB_DCHECK(!valid_);
    valid_ = true;
  }
  T Detach() {
    SB_DCHECK(valid_);
    valid_ = false;
    return value_;
  }

 private:
  bool valid_;
  T value_;
  CloseFunc close_func_;
};

class HWParams
    : public AutoClose<snd_pcm_hw_params_t*, void (*)(snd_pcm_hw_params_t*)> {
 public:
  HWParams() : AutoClose(snd_pcm_hw_params_free) {}
};

class SWParams
    : public AutoClose<snd_pcm_sw_params_t*, void (*)(snd_pcm_sw_params_t*)> {
 public:
  SWParams() : AutoClose(snd_pcm_sw_params_free) {}
};

class PcmHandle : public AutoClose<snd_pcm_t*, int (*)(snd_pcm_t*)> {
 public:
  PcmHandle() : AutoClose(snd_pcm_close) {}
};

}  // namespace

void* AlsaOpenPlaybackDevice(int channel,
                             int sample_rate,
                             int frames_per_request,
                             int buffer_size_in_frames,
                             snd_pcm_format_t sample_type) {
  SB_DCHECK(sample_type == SND_PCM_FORMAT_FLOAT_LE ||
            sample_type == SND_PCM_FORMAT_S16);

  PcmHandle playback_handle;
  int error =
      snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
  ALSA_CHECK(error, snd_pcm_open, NULL);
  playback_handle.set_valid();

  HWParams hw_params;
  error = snd_pcm_hw_params_malloc(&hw_params);
  ALSA_CHECK(error, snd_pcm_hw_params_malloc, NULL);
  hw_params.set_valid();

  error = snd_pcm_hw_params_any(playback_handle, hw_params);
  ALSA_CHECK(error, snd_pcm_hw_params_any, NULL);

  error = snd_pcm_hw_params_set_access(playback_handle, hw_params,
                                       SND_PCM_ACCESS_RW_INTERLEAVED);
  ALSA_CHECK(error, snd_pcm_hw_params_set_access, NULL);

  error = snd_pcm_hw_params_set_format(playback_handle, hw_params, sample_type);
  ALSA_CHECK(error, snd_pcm_hw_params_set_format, NULL);

  error =
      snd_pcm_hw_params_set_rate(playback_handle, hw_params, sample_rate, 0);
  ALSA_CHECK(error, snd_pcm_hw_params_set_rate, NULL);

  error = snd_pcm_hw_params_set_channels(playback_handle, hw_params, channel);
  ALSA_CHECK(error, snd_pcm_hw_params_set_channels, NULL);

  snd_pcm_uframes_t buffer_size = buffer_size_in_frames;
  error = snd_pcm_hw_params_set_buffer_size_near(playback_handle, hw_params,
                                                 &buffer_size);
  ALSA_CHECK(error, snd_pcm_hw_params_set_buffer_size, NULL);

  error = snd_pcm_hw_params(playback_handle, hw_params);
  ALSA_CHECK(error, snd_pcm_hw_params, NULL);

  SWParams sw_params;
  error = snd_pcm_sw_params_malloc(&sw_params);
  ALSA_CHECK(error, snd_pcm_sw_params_malloc, NULL);
  sw_params.set_valid();

  error = snd_pcm_sw_params_current(playback_handle, sw_params);
  ALSA_CHECK(error, snd_pcm_sw_params_current, NULL);

  error = snd_pcm_sw_params_set_avail_min(playback_handle, sw_params,
                                          frames_per_request);
  ALSA_CHECK(error, snd_pcm_sw_params_set_avail_min, NULL);

  error = snd_pcm_sw_params_set_silence_threshold(playback_handle, sw_params,
                                                  kSilenceThresholdInFrames);
  ALSA_CHECK(error, snd_pcm_sw_params_set_silence_threshold, NULL);

  error = snd_pcm_sw_params_set_start_threshold(playback_handle, sw_params,
                                                kStartThresholdInFrames);
  ALSA_CHECK(error, snd_pcm_sw_params_set_start_threshold, NULL);

  error = snd_pcm_sw_params(playback_handle, sw_params);
  ALSA_CHECK(error, snd_pcm_sw_params, NULL);

  error = snd_pcm_prepare(playback_handle);
  ALSA_CHECK(error, snd_pcm_prepare, NULL);

  return playback_handle.Detach();
}

int AlsaWriteFrames(void* playback_handle,
                    const void* buffer,
                    int frames_to_write) {
  if (frames_to_write == 0) {
    return 0;
  }

  int error;
  snd_pcm_t* handle = reinterpret_cast<snd_pcm_t*>(playback_handle);

  int frames = 0;
  for (;;) {
    frames = snd_pcm_writei(handle, buffer, frames_to_write);
    if (frames > 0) {
      return frames;
    } else if (frames == -EPIPE) {
      error = snd_pcm_prepare(handle);
      ALSA_CHECK(error, snd_pcm_prepare, 0);
    } else {
      ALSA_CHECK(frames, snd_pcm_writei, 0);
      // "frames == 0" means snd_pcm_writei() is interrupted, we'll retry.
    }
  }

  SB_NOTREACHED();
  return 0;
}

int AlsaGetBufferedFrames(void* playback_handle) {
  int error;
  snd_pcm_t* handle = reinterpret_cast<snd_pcm_t*>(playback_handle);
  int state = snd_pcm_state(handle);
  // snd_pcm_delay() isn't able to catch xrun or setup, so we explicitly check
  // for them.
  if (state == SND_PCM_STATE_XRUN || state == SND_PCM_STATE_SETUP) {
    error = snd_pcm_prepare(handle);
    ALSA_CHECK(error, snd_pcm_prepare, -1);
    // The buffer has already been reset, so the delay is 0.
    return 0;
  }

  snd_pcm_sframes_t delay;
  error = snd_pcm_delay(handle, &delay);
  if (error == 0) {
    if (delay < 0) {
      SB_LOG(ERROR) << __FUNCTION__
                    << ": snd_pcm_delay() failed with negative delay " << delay;
      return -1;
    }
    return delay;
  }
  ALSA_CHECK(error, snd_pcm_delay, -1);
  return -1;
}

void AlsaCloseDevice(void* playback_handle) {
  if (playback_handle) {
    snd_pcm_drain(reinterpret_cast<snd_pcm_t*>(playback_handle));
    snd_pcm_close(reinterpret_cast<snd_pcm_t*>(playback_handle));
  }
}

void AlsaDrain(void* playback_handle) {
  if (playback_handle) {
    snd_pcm_t* handle = reinterpret_cast<snd_pcm_t*>(playback_handle);

    int error;
    error = snd_pcm_drain(handle);
    SB_DCHECK(error >= 0);
  }
}

}  // namespace alsa
}  // namespace shared
}  // namespace starboard
