/*
 *  Copyright (c) 2012 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_VOICE_ENGINE_VOE_BASE_IMPL_H
#define WEBRTC_VOICE_ENGINE_VOE_BASE_IMPL_H

#include "webrtc/voice_engine/include/voe_base.h"

#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/voice_engine/shared_data.h"

namespace webrtc {

class ProcessThread;

class VoEBaseImpl : public VoEBase,
                    public AudioTransport,
                    public AudioDeviceObserver {
 public:
  int RegisterVoiceEngineObserver(VoiceEngineObserver& observer) override;
  int DeRegisterVoiceEngineObserver() override;

  int Init(AudioDeviceModule* external_adm = nullptr,
           AudioProcessing* audioproc = nullptr) override;
  AudioProcessing* audio_processing() override {
    return shared_->audio_processing();
  }
  int Terminate() override;

  int CreateChannel() override;
  int CreateChannel(const Config& config) override;
  int DeleteChannel(int channel) override;

  int StartReceive(int channel) override;
  int StartPlayout(int channel) override;
  int StartSend(int channel) override;
  int StopReceive(int channel) override;
  int StopPlayout(int channel) override;
  int StopSend(int channel) override;

  int GetVersion(char version[1024]) override;

  int LastError() override;

  AudioTransport* audio_transport() override { return this; }

  int AssociateSendChannel(int channel, int accociate_send_channel) override;

  // AudioTransport
  int32_t RecordedDataIsAvailable(const void* audioSamples, size_t nSamples,
                                  size_t nBytesPerSample, uint8_t nChannels,
                                  uint32_t samplesPerSec, uint32_t totalDelayMS,
                                  int32_t clockDrift, uint32_t micLevel,
                                  bool keyPressed,
                                  uint32_t& newMicLevel) override;
  int32_t NeedMorePlayData(size_t nSamples, size_t nBytesPerSample,
                           uint8_t nChannels, uint32_t samplesPerSec,
                           void* audioSamples, size_t& nSamplesOut,
                           int64_t* elapsed_time_ms,
                           int64_t* ntp_time_ms) override;
  int OnDataAvailable(const int voe_channels[], int number_of_voe_channels,
                      const int16_t* audio_data, int sample_rate,
                      int number_of_channels, size_t number_of_frames,
                      int audio_delay_milliseconds, int volume,
                      bool key_pressed, bool need_audio_processing) override;
  void OnData(int voe_channel, const void* audio_data, int bits_per_sample,
              int sample_rate, int number_of_channels,
              size_t number_of_frames) override;
  void PushCaptureData(int voe_channel, const void* audio_data,
                       int bits_per_sample, int sample_rate,
                       int number_of_channels,
                       size_t number_of_frames) override;
  void PullRenderData(int bits_per_sample, int sample_rate,
                      int number_of_channels, size_t number_of_frames,
                      void* audio_data, int64_t* elapsed_time_ms,
                      int64_t* ntp_time_ms) override;

  // AudioDeviceObserver
  void OnErrorIsReported(ErrorCode error) override;
  void OnWarningIsReported(WarningCode warning) override;

 protected:
  VoEBaseImpl(voe::SharedData* shared);
  ~VoEBaseImpl() override;

 private:
  int32_t StartPlayout();
  int32_t StopPlayout();
  int32_t StartSend();
  int32_t StopSend();
  int32_t TerminateInternal();

  // Helper function to process the recorded data with AudioProcessing Module,
  // demultiplex the data to specific voe channels, encode and send to the
  // network. When |number_of_VoE_channels| is 0, it will demultiplex the
  // data to all the existing VoE channels.
  // It returns new AGC microphone volume or 0 if no volume changes
  // should be done.
  int ProcessRecordedDataWithAPM(
      const int voe_channels[], int number_of_voe_channels,
      const void* audio_data, uint32_t sample_rate, uint8_t number_of_channels,
      size_t number_of_frames, uint32_t audio_delay_milliseconds,
      int32_t clock_drift, uint32_t volume, bool key_pressed);

  void GetPlayoutData(int sample_rate, int number_of_channels,
                      size_t number_of_frames, bool feed_data_to_apm,
                      void* audio_data, int64_t* elapsed_time_ms,
                      int64_t* ntp_time_ms);

  int32_t AddVoEVersion(char* str) const;

  // Initialize channel by setting Engine Information then initializing
  // channel.
  int InitializeChannel(voe::ChannelOwner* channel_owner);
#ifdef WEBRTC_EXTERNAL_TRANSPORT
  int32_t AddExternalTransportBuild(char* str) const;
#endif
  VoiceEngineObserver* voiceEngineObserverPtr_;
  CriticalSectionWrapper& callbackCritSect_;

  AudioFrame audioFrame_;
  voe::SharedData* shared_;
};

}  // namespace webrtc

#endif  // WEBRTC_VOICE_ENGINE_VOE_BASE_IMPL_H
