/*
 *  Copyright (c) 2015 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_TEST_AUTO_TEST_FAKES_CONFERENCE_TRANSPORT_H_
#define WEBRTC_VOICE_ENGINE_TEST_AUTO_TEST_FAKES_CONFERENCE_TRANSPORT_H_

#include <deque>
#include <map>
#include <utility>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/basictypes.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/system_wrappers/include/thread_wrapper.h"
#include "webrtc/voice_engine/include/voe_base.h"
#include "webrtc/voice_engine/include/voe_codec.h"
#include "webrtc/voice_engine/include/voe_file.h"
#include "webrtc/voice_engine/include/voe_network.h"
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
#include "webrtc/voice_engine/test/auto_test/fakes/loudest_filter.h"

static const size_t kMaxPacketSizeByte = 1500;

namespace voetest {

// This class is to simulate a conference call. There are two Voice Engines, one
// for local channels and the other for remote channels. There is a simulated
// reflector, which exchanges RTCP with local channels. For simplicity, it
// also uses the Voice Engine for remote channels. One can add streams by
// calling AddStream(), which creates a remote sender channel and a local
// receive channel. The remote sender channel plays a file as microphone in a
// looped fashion. Received streams are mixed and played.

class ConferenceTransport: public webrtc::Transport {
 public:
  ConferenceTransport();
  virtual ~ConferenceTransport();

  /* SetRtt()
   * Set RTT between local channels and reflector.
   *
   * Input:
   *   rtt_ms : RTT in milliseconds.
   */
  void SetRtt(unsigned int rtt_ms);

  /* AddStream()
   * Adds a stream in the conference.
   *
   * Input:
   *   file_name : name of the file to be added as microphone input.
   *   format    : format of the input file.
   *
   * Returns stream id.
   */
  unsigned int AddStream(std::string file_name, webrtc::FileFormats format);

  /* RemoveStream()
   * Removes a stream with specified ID from the conference.
   *
   * Input:
   *   id : stream id.
   *
   * Returns false if the specified stream does not exist, true if succeeds.
   */
  bool RemoveStream(unsigned int id);

  /* StartPlayout()
   * Starts playing out the stream with specified ID, using the default device.
   *
   * Input:
   *   id : stream id.
   *
   * Returns false if the specified stream does not exist, true if succeeds.
   */
  bool StartPlayout(unsigned int id);

  /* GetReceiverStatistics()
   * Gets RTCP statistics of the stream with specified ID.
   *
   * Input:
   *   id : stream id;
   *   stats : pointer to a CallStatistics to store the result.
   *
   * Returns false if the specified stream does not exist, true if succeeds.
   */
  bool GetReceiverStatistics(unsigned int id, webrtc::CallStatistics* stats);

  // Inherit from class webrtc::Transport.
  bool SendRtp(const uint8_t* data,
               size_t len,
               const webrtc::PacketOptions& options) override;
  bool SendRtcp(const uint8_t *data, size_t len) override;

 private:
  struct Packet {
    enum Type { Rtp, Rtcp, } type_;

    Packet() : len_(0) {}
    Packet(Type type, const void* data, size_t len, uint32_t time_ms)
        : type_(type), len_(len), send_time_ms_(time_ms) {
      EXPECT_LE(len_, kMaxPacketSizeByte);
      memcpy(data_, data, len_);
    }

    uint8_t data_[kMaxPacketSizeByte];
    size_t len_;
    uint32_t send_time_ms_;
  };

  static bool Run(void* transport) {
    return static_cast<ConferenceTransport*>(transport)->DispatchPackets();
  }

  int GetReceiverChannelForSsrc(unsigned int sender_ssrc) const;
  void StorePacket(Packet::Type type, const void* data, size_t len);
  void SendPacket(const Packet& packet);
  bool DispatchPackets();

  const rtc::scoped_ptr<webrtc::CriticalSectionWrapper> pq_crit_;
  const rtc::scoped_ptr<webrtc::CriticalSectionWrapper> stream_crit_;
  const rtc::scoped_ptr<webrtc::EventWrapper> packet_event_;
  const rtc::scoped_ptr<webrtc::ThreadWrapper> thread_;

  unsigned int rtt_ms_;
  unsigned int stream_count_;

  std::map<unsigned int, std::pair<int, int>> streams_
    GUARDED_BY(stream_crit_.get());
  std::deque<Packet> packet_queue_ GUARDED_BY(pq_crit_.get());

  int local_sender_;  // Channel Id of local sender
  int reflector_;

  webrtc::VoiceEngine* local_voe_;
  webrtc::VoEBase* local_base_;
  webrtc::VoERTP_RTCP* local_rtp_rtcp_;
  webrtc::VoENetwork* local_network_;

  webrtc::VoiceEngine* remote_voe_;
  webrtc::VoEBase* remote_base_;
  webrtc::VoECodec* remote_codec_;
  webrtc::VoERTP_RTCP* remote_rtp_rtcp_;
  webrtc::VoENetwork* remote_network_;
  webrtc::VoEFile* remote_file_;

  LoudestFilter loudest_filter_;

  const rtc::scoped_ptr<webrtc::RtpHeaderParser> rtp_header_parser_;
};
}  // namespace voetest

#endif  // WEBRTC_VOICE_ENGINE_TEST_AUTO_TEST_FAKES_CONFERENCE_TRANSPORT_H_
