/*
 *  Copyright (c) 2013 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.
 */

#ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_DEVICE_TEMPLATE_H_
#define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_DEVICE_TEMPLATE_H_

#include "webrtc/modules/audio_device/android/audio_manager.h"
#include "webrtc/modules/audio_device/audio_device_generic.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/rtc_base/thread_checker.h"

namespace webrtc {

// InputType/OutputType can be any class that implements the capturing/rendering
// part of the AudioDeviceGeneric API.
// Construction and destruction must be done on one and the same thread. Each
// internal implementation of InputType and OutputType will RTC_DCHECK if that
// is not the case. All implemented methods must also be called on the same
// thread. See comments in each InputType/OutputType class for more info.
// It is possible to call the two static methods (SetAndroidAudioDeviceObjects
// and ClearAndroidAudioDeviceObjects) from a different thread but both will
// RTC_CHECK that the calling thread is attached to a Java VM.

template <class InputType, class OutputType>
class AudioDeviceTemplate : public AudioDeviceGeneric {
 public:
  AudioDeviceTemplate(AudioDeviceModule::AudioLayer audio_layer,
                      AudioManager* audio_manager)
      : audio_layer_(audio_layer),
        audio_manager_(audio_manager),
        output_(audio_manager_),
        input_(audio_manager_),
        initialized_(false) {
    LOG(INFO) << __FUNCTION__;
    RTC_CHECK(audio_manager);
    audio_manager_->SetActiveAudioLayer(audio_layer);
  }

  virtual ~AudioDeviceTemplate() { LOG(INFO) << __FUNCTION__; }

  int32_t ActiveAudioLayer(
      AudioDeviceModule::AudioLayer& audioLayer) const override {
    LOG(INFO) << __FUNCTION__;
    audioLayer = audio_layer_;
    return 0;
  }

  InitStatus Init() override {
    LOG(INFO) << __FUNCTION__;
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    RTC_DCHECK(!initialized_);
    if (!audio_manager_->Init()) {
      return InitStatus::OTHER_ERROR;
    }
    if (output_.Init() != 0) {
      audio_manager_->Close();
      return InitStatus::PLAYOUT_ERROR;
    }
    if (input_.Init() != 0) {
      output_.Terminate();
      audio_manager_->Close();
      return InitStatus::RECORDING_ERROR;
    }
    initialized_ = true;
    return InitStatus::OK;
  }

  int32_t Terminate() override {
    LOG(INFO) << __FUNCTION__;
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    int32_t err = input_.Terminate();
    err |= output_.Terminate();
    err |= !audio_manager_->Close();
    initialized_ = false;
    RTC_DCHECK_EQ(err, 0);
    return err;
  }

  bool Initialized() const override {
    LOG(INFO) << __FUNCTION__;
    RTC_DCHECK(thread_checker_.CalledOnValidThread());
    return initialized_;
  }

  int16_t PlayoutDevices() override {
    LOG(INFO) << __FUNCTION__;
    return 1;
  }

  int16_t RecordingDevices() override {
    LOG(INFO) << __FUNCTION__;
    return 1;
  }

  int32_t PlayoutDeviceName(
      uint16_t index,
      char name[kAdmMaxDeviceNameSize],
      char guid[kAdmMaxGuidSize]) override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t RecordingDeviceName(
      uint16_t index,
      char name[kAdmMaxDeviceNameSize],
      char guid[kAdmMaxGuidSize]) override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t SetPlayoutDevice(uint16_t index) override {
    // OK to use but it has no effect currently since device selection is
    // done using Andoid APIs instead.
    LOG(INFO) << __FUNCTION__;
    return 0;
  }

  int32_t SetPlayoutDevice(
      AudioDeviceModule::WindowsDeviceType device) override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t SetRecordingDevice(uint16_t index) override {
    // OK to use but it has no effect currently since device selection is
    // done using Andoid APIs instead.
    LOG(INFO) << __FUNCTION__;
    return 0;
  }

  int32_t SetRecordingDevice(
      AudioDeviceModule::WindowsDeviceType device) override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t PlayoutIsAvailable(bool& available) override {
    LOG(INFO) << __FUNCTION__;
    available = true;
    return 0;
  }

  int32_t InitPlayout() override {
    LOG(INFO) << __FUNCTION__;
    return output_.InitPlayout();
  }

  bool PlayoutIsInitialized() const override {
    LOG(INFO) << __FUNCTION__;
    return output_.PlayoutIsInitialized();
  }

  int32_t RecordingIsAvailable(bool& available) override {
    LOG(INFO) << __FUNCTION__;
    available = true;
    return 0;
  }

  int32_t InitRecording() override {
    LOG(INFO) << __FUNCTION__;
    return input_.InitRecording();
  }

  bool RecordingIsInitialized() const override {
    LOG(INFO) << __FUNCTION__;
    return input_.RecordingIsInitialized();
  }

  int32_t StartPlayout() override {
    LOG(INFO) << __FUNCTION__;
    if (!audio_manager_->IsCommunicationModeEnabled()) {
      LOG(WARNING)
          << "The application should use MODE_IN_COMMUNICATION audio mode!";
    }
    return output_.StartPlayout();
  }

  int32_t StopPlayout() override {
    // Avoid using audio manger (JNI/Java cost) if playout was inactive.
    if (!Playing())
      return 0;
    LOG(INFO) << __FUNCTION__;
    int32_t err = output_.StopPlayout();
    return err;
  }

  bool Playing() const override {
    LOG(INFO) << __FUNCTION__;
    return output_.Playing();
  }

  int32_t StartRecording() override {
    LOG(INFO) << __FUNCTION__;
    if (!audio_manager_->IsCommunicationModeEnabled()) {
      LOG(WARNING)
          << "The application should use MODE_IN_COMMUNICATION audio mode!";
    }
    return input_.StartRecording();
  }

  int32_t StopRecording() override {
    // Avoid using audio manger (JNI/Java cost) if recording was inactive.
    LOG(INFO) << __FUNCTION__;
    if (!Recording())
      return 0;
    int32_t err = input_.StopRecording();
    return err;
  }

  bool Recording() const override {
    return input_.Recording() ;
  }

  int32_t SetAGC(bool enable) override {
    if (enable) {
      FATAL() << "Should never be called";
    }
    return -1;
  }

  bool AGC() const override {
    LOG(INFO) << __FUNCTION__;
    return false;
  }

  int32_t InitSpeaker() override {
    LOG(INFO) << __FUNCTION__;
    return 0;
  }

  bool SpeakerIsInitialized() const override {
    LOG(INFO) << __FUNCTION__;
    return true;
  }

  int32_t InitMicrophone() override {
    LOG(INFO) << __FUNCTION__;
    return 0;
  }

  bool MicrophoneIsInitialized() const override {
    LOG(INFO) << __FUNCTION__;
    return true;
  }

  int32_t SpeakerVolumeIsAvailable(bool& available) override {
    LOG(INFO) << __FUNCTION__;
    return output_.SpeakerVolumeIsAvailable(available);
  }

  int32_t SetSpeakerVolume(uint32_t volume) override {
    LOG(INFO) << __FUNCTION__;
    return output_.SetSpeakerVolume(volume);
  }

  int32_t SpeakerVolume(uint32_t& volume) const override {
    LOG(INFO) << __FUNCTION__;
    return output_.SpeakerVolume(volume);
  }

  int32_t MaxSpeakerVolume(uint32_t& maxVolume) const override {
    LOG(INFO) << __FUNCTION__;
    return output_.MaxSpeakerVolume(maxVolume);
  }

  int32_t MinSpeakerVolume(uint32_t& minVolume) const override {
    LOG(INFO) << __FUNCTION__;
    return output_.MinSpeakerVolume(minVolume);
  }

  int32_t MicrophoneVolumeIsAvailable(bool& available) override{
    available = false;
    return -1;
  }

  int32_t SetMicrophoneVolume(uint32_t volume) override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t MicrophoneVolume(uint32_t& volume) const override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t MinMicrophoneVolume(uint32_t& minVolume) const override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t SpeakerMuteIsAvailable(bool& available) override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t SetSpeakerMute(bool enable) override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t SpeakerMute(bool& enabled) const override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t MicrophoneMuteIsAvailable(bool& available) override {
    FATAL() << "Not implemented";
    return -1;
  }

  int32_t SetMicrophoneMute(bool enable) override {
    FATAL() << "Not implemented";
    return -1;
  }

  int32_t MicrophoneMute(bool& enabled) const override {
    FATAL() << "Not implemented";
    return -1;
  }

  int32_t StereoPlayoutIsAvailable(bool& available) override {
    LOG(INFO) << __FUNCTION__;
    available = false;
    return 0;
  }

  // TODO(henrika): add support.
  int32_t SetStereoPlayout(bool enable) override {
    LOG(INFO) << __FUNCTION__;
    // Allow disabling stereo playout, as that matches returning false(0) from
    // StereoPlayoutIsAvailable and is the default case.
    return enable ? -1 : 0;
  }

  // TODO(henrika): add support.
  int32_t StereoPlayout(bool& enabled) const override {
    enabled = false;
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t StereoRecordingIsAvailable(bool& available) override {
    LOG(INFO) << __FUNCTION__;
    available = false;
    return 0;
  }

  int32_t SetStereoRecording(bool enable) override {
    LOG(INFO) << __FUNCTION__;
    return -1;
  }

  int32_t StereoRecording(bool& enabled) const override {
    LOG(INFO) << __FUNCTION__;
    enabled = false;
    return 0;
  }

  int32_t PlayoutDelay(uint16_t& delay_ms) const override {
    // Best guess we can do is to use half of the estimated total delay.
    delay_ms = audio_manager_->GetDelayEstimateInMilliseconds() / 2;
    RTC_DCHECK_GT(delay_ms, 0);
    return 0;
  }

  int32_t RecordingDelay(uint16_t& delay_ms) const override {
    // Best guess we can do is to use half of the estimated total delay.
    LOG(INFO) << __FUNCTION__;
    delay_ms = audio_manager_->GetDelayEstimateInMilliseconds() / 2;
    RTC_DCHECK_GT(delay_ms, 0);
    return 0;
  }

  bool PlayoutWarning() const override {
    return false;
  }

  bool PlayoutError() const override {
    return false;
  }

  bool RecordingWarning() const override {
    return false;
  }

  bool RecordingError() const override {
    return false;
  }

  void ClearPlayoutWarning() override { LOG(INFO) << __FUNCTION__; }

  void ClearPlayoutError() override { LOG(INFO) << __FUNCTION__; }

  void ClearRecordingWarning() override { LOG(INFO) << __FUNCTION__; }

  void ClearRecordingError() override { LOG(INFO) << __FUNCTION__; }

  void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override {
    LOG(INFO) << __FUNCTION__;
    output_.AttachAudioBuffer(audioBuffer);
    input_.AttachAudioBuffer(audioBuffer);
  }

  // TODO(henrika): remove
  int32_t SetPlayoutSampleRate(const uint32_t samplesPerSec) override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t SetLoudspeakerStatus(bool enable) override {
    FATAL() << "Should never be called";
    return -1;
  }

  int32_t GetLoudspeakerStatus(bool& enable) const override {
    FATAL() << "Should never be called";
    return -1;
  }

  // Returns true if the device both supports built in AEC and the device
  // is not blacklisted.
  // Currently, if OpenSL ES is used in both directions, this method will still
  // report the correct value and it has the correct effect. As an example:
  // a device supports built in AEC and this method returns true. Libjingle
  // will then disable the WebRTC based AEC and that will work for all devices
  // (mainly Nexus) even when OpenSL ES is used for input since our current
  // implementation will enable built-in AEC by default also for OpenSL ES.
  // The only "bad" thing that happens today is that when Libjingle calls
  // OpenSLESRecorder::EnableBuiltInAEC() it will not have any real effect and
  // a "Not Implemented" log will be filed. This non-perfect state will remain
  // until I have added full support for audio effects based on OpenSL ES APIs.
  bool BuiltInAECIsAvailable() const override {
    LOG(INFO) << __FUNCTION__;
    return audio_manager_->IsAcousticEchoCancelerSupported();
  }

  // TODO(henrika): add implementation for OpenSL ES based audio as well.
  int32_t EnableBuiltInAEC(bool enable) override {
    LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
    RTC_CHECK(BuiltInAECIsAvailable()) << "HW AEC is not available";
    return input_.EnableBuiltInAEC(enable);
  }

  // Returns true if the device both supports built in AGC and the device
  // is not blacklisted.
  // TODO(henrika): add implementation for OpenSL ES based audio as well.
  // In addition, see comments for BuiltInAECIsAvailable().
  bool BuiltInAGCIsAvailable() const override {
    LOG(INFO) << __FUNCTION__;
    return audio_manager_->IsAutomaticGainControlSupported();
  }

  // TODO(henrika): add implementation for OpenSL ES based audio as well.
  int32_t EnableBuiltInAGC(bool enable) override {
    LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
    RTC_CHECK(BuiltInAGCIsAvailable()) << "HW AGC is not available";
    return input_.EnableBuiltInAGC(enable);
  }

  // Returns true if the device both supports built in NS and the device
  // is not blacklisted.
  // TODO(henrika): add implementation for OpenSL ES based audio as well.
  // In addition, see comments for BuiltInAECIsAvailable().
  bool BuiltInNSIsAvailable() const override {
    LOG(INFO) << __FUNCTION__;
    return audio_manager_->IsNoiseSuppressorSupported();
  }

  // TODO(henrika): add implementation for OpenSL ES based audio as well.
  int32_t EnableBuiltInNS(bool enable) override {
    LOG(INFO) << __FUNCTION__ << "(" << enable << ")";
    RTC_CHECK(BuiltInNSIsAvailable()) << "HW NS is not available";
    return input_.EnableBuiltInNS(enable);
  }

 private:
  rtc::ThreadChecker thread_checker_;

  // Local copy of the audio layer set during construction of the
  // AudioDeviceModuleImpl instance. Read only value.
  const AudioDeviceModule::AudioLayer audio_layer_;

  // Non-owning raw pointer to AudioManager instance given to use at
  // construction. The real object is owned by AudioDeviceModuleImpl and the
  // life time is the same as that of the AudioDeviceModuleImpl, hence there
  // is no risk of reading a NULL pointer at any time in this class.
  AudioManager* const audio_manager_;

  OutputType output_;

  InputType input_;

  bool initialized_;
};

}  // namespace webrtc

#endif  // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_DEVICE_TEMPLATE_H_
