/*
 *  Copyright (c) 2020 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 AUDIO_VOIP_VOIP_CORE_H_
#define AUDIO_VOIP_VOIP_CORE_H_

#include <map>
#include <memory>
#include <queue>
#include <unordered_map>
#include <vector>

#include "api/audio_codecs/audio_decoder_factory.h"
#include "api/audio_codecs/audio_encoder_factory.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/voip/voip_base.h"
#include "api/voip/voip_codec.h"
#include "api/voip/voip_dtmf.h"
#include "api/voip/voip_engine.h"
#include "api/voip/voip_network.h"
#include "api/voip/voip_statistics.h"
#include "api/voip/voip_volume_control.h"
#include "audio/audio_transport_impl.h"
#include "audio/voip/audio_channel.h"
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_mixer/audio_mixer_impl.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/utility/include/process_thread.h"
#include "rtc_base/synchronization/mutex.h"

namespace webrtc {

// VoipCore is the implementatino of VoIP APIs listed in api/voip directory.
// It manages a vector of AudioChannel objects where each is mapped with a
// ChannelId (int) type. ChannelId is the primary key to locate a specific
// AudioChannel object to operate requested VoIP API from the caller.
//
// This class receives required audio components from caller at construction and
// owns the life cycle of them to orchestrate the proper destruction sequence.
class VoipCore : public VoipEngine,
                 public VoipBase,
                 public VoipNetwork,
                 public VoipCodec,
                 public VoipDtmf,
                 public VoipStatistics,
                 public VoipVolumeControl {
 public:
  // Construct VoipCore with provided arguments.
  // ProcessThread implementation can be injected by |process_thread|
  // (mainly for testing purpose) and when set to nullptr, default
  // implementation will be used.
  VoipCore(rtc::scoped_refptr<AudioEncoderFactory> encoder_factory,
           rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
           std::unique_ptr<TaskQueueFactory> task_queue_factory,
           rtc::scoped_refptr<AudioDeviceModule> audio_device_module,
           rtc::scoped_refptr<AudioProcessing> audio_processing,
           std::unique_ptr<ProcessThread> process_thread = nullptr);
  ~VoipCore() override = default;

  // Implements VoipEngine interfaces.
  VoipBase& Base() override { return *this; }
  VoipNetwork& Network() override { return *this; }
  VoipCodec& Codec() override { return *this; }
  VoipDtmf& Dtmf() override { return *this; }
  VoipStatistics& Statistics() override { return *this; }
  VoipVolumeControl& VolumeControl() override { return *this; }

  // Implements VoipBase interfaces.
  ChannelId CreateChannel(Transport* transport,
                          absl::optional<uint32_t> local_ssrc) override;
  VoipResult ReleaseChannel(ChannelId channel_id) override;
  VoipResult StartSend(ChannelId channel_id) override;
  VoipResult StopSend(ChannelId channel_id) override;
  VoipResult StartPlayout(ChannelId channel_id) override;
  VoipResult StopPlayout(ChannelId channel_id) override;

  // Implements VoipNetwork interfaces.
  VoipResult ReceivedRTPPacket(
      ChannelId channel_id,
      rtc::ArrayView<const uint8_t> rtp_packet) override;
  VoipResult ReceivedRTCPPacket(
      ChannelId channel_id,
      rtc::ArrayView<const uint8_t> rtcp_packet) override;

  // Implements VoipCodec interfaces.
  VoipResult SetSendCodec(ChannelId channel_id,
                          int payload_type,
                          const SdpAudioFormat& encoder_format) override;
  VoipResult SetReceiveCodecs(
      ChannelId channel_id,
      const std::map<int, SdpAudioFormat>& decoder_specs) override;

  // Implements VoipDtmf interfaces.
  VoipResult RegisterTelephoneEventType(ChannelId channel_id,
                                        int rtp_payload_type,
                                        int sample_rate_hz) override;
  VoipResult SendDtmfEvent(ChannelId channel_id,
                           DtmfEvent dtmf_event,
                           int duration_ms) override;

  // Implements VoipStatistics interfaces.
  VoipResult GetIngressStatistics(ChannelId channel_id,
                                  IngressStatistics& ingress_stats) override;
  VoipResult GetChannelStatistics(ChannelId channe_id,
                                  ChannelStatistics& channel_stats) override;

  // Implements VoipVolumeControl interfaces.
  VoipResult SetInputMuted(ChannelId channel_id, bool enable) override;
  VoipResult GetInputVolumeInfo(ChannelId channel_id,
                                VolumeInfo& volume_info) override;
  VoipResult GetOutputVolumeInfo(ChannelId channel_id,
                                 VolumeInfo& volume_info) override;

 private:
  // Initialize ADM and default audio device if needed.
  // Returns true if ADM is successfully initialized or already in such state
  // (e.g called more than once). Returns false when ADM fails to initialize
  // which would presumably render further processing useless. Note that such
  // failure won't necessarily succeed in next initialization attempt as it
  // would mean changing the ADM implementation. From Android N and onwards, the
  // mobile app may not be able to gain microphone access when in background
  // mode. Therefore it would be better to delay the logic as late as possible.
  bool InitializeIfNeeded();

  // Fetches the corresponding AudioChannel assigned with given |channel|.
  // Returns nullptr if not found.
  rtc::scoped_refptr<AudioChannel> GetChannel(ChannelId channel_id);

  // Updates AudioTransportImpl with a new set of actively sending AudioSender
  // (AudioEgress). This needs to be invoked whenever StartSend/StopSend is
  // involved by caller. Returns false when the selected audio device fails to
  // initialize where it can't expect to deliver any audio input sample.
  bool UpdateAudioTransportWithSenders();

  // Synchronization for these are handled internally.
  rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
  rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
  std::unique_ptr<TaskQueueFactory> task_queue_factory_;

  // Synchronization is handled internally by AudioProcessing.
  // Must be placed before |audio_device_module_| for proper destruction.
  rtc::scoped_refptr<AudioProcessing> audio_processing_;

  // Synchronization is handled internally by AudioMixer.
  // Must be placed before |audio_device_module_| for proper destruction.
  rtc::scoped_refptr<AudioMixer> audio_mixer_;

  // Synchronization is handled internally by AudioTransportImpl.
  // Must be placed before |audio_device_module_| for proper destruction.
  std::unique_ptr<AudioTransportImpl> audio_transport_;

  // Synchronization is handled internally by AudioDeviceModule.
  rtc::scoped_refptr<AudioDeviceModule> audio_device_module_;

  // Synchronization is handled internally by ProcessThread.
  // Must be placed before |channels_| for proper destruction.
  std::unique_ptr<ProcessThread> process_thread_;

  Mutex lock_;

  // Member to track a next ChannelId for new AudioChannel.
  int next_channel_id_ RTC_GUARDED_BY(lock_) = 0;

  // Container to track currently active AudioChannel objects mapped by
  // ChannelId.
  std::unordered_map<ChannelId, rtc::scoped_refptr<AudioChannel>> channels_
      RTC_GUARDED_BY(lock_);

  // Boolean flag to ensure initialization only occurs once.
  bool initialized_ RTC_GUARDED_BY(lock_) = false;
};

}  // namespace webrtc

#endif  // AUDIO_VOIP_VOIP_CORE_H_
