/*
 *  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/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/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.
  int SendPacket(int channel, const void *data, size_t len) override;
  int SendRTCPPacket(int channel, const void *data, size_t len) override;

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

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

    int channel_;
    uint8_t data_[kMaxPacketSizeByte];
    size_t len_;
    uint32 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, int channel, 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_
