/*
 *  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;

  // 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_
