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

#include "webrtc/voice_engine/test/auto_test/fakes/conference_transport.h"

#include <string>

#include "webrtc/base/byteorder.h"
#include "webrtc/base/timeutils.h"
#include "webrtc/system_wrappers/interface/sleep.h"

namespace {
  static const unsigned int kReflectorSsrc = 0x0000;
  static const unsigned int kLocalSsrc = 0x0001;
  static const unsigned int kFirstRemoteSsrc = 0x0002;
  static const webrtc::CodecInst kCodecInst =
      {120, "opus", 48000, 960, 2, 64000};
  static const int kAudioLevelHeaderId = 1;

  static unsigned int ParseRtcpSsrc(const void* data, size_t len) {
    const size_t ssrc_pos = 4;
    unsigned int ssrc = 0;
    if (len >= (ssrc_pos + sizeof(ssrc))) {
      ssrc = rtc::GetBE32(static_cast<const char*>(data) + ssrc_pos);
    }
    return ssrc;
  }
}  // namespace

namespace voetest {

ConferenceTransport::ConferenceTransport()
    : pq_crit_(webrtc::CriticalSectionWrapper::CreateCriticalSection()),
      stream_crit_(webrtc::CriticalSectionWrapper::CreateCriticalSection()),
      packet_event_(webrtc::EventWrapper::Create()),
      thread_(webrtc::ThreadWrapper::CreateThread(Run,
                                                  this,
                                                  "ConferenceTransport")),
      rtt_ms_(0),
      stream_count_(0),
      rtp_header_parser_(webrtc::RtpHeaderParser::Create()) {
  rtp_header_parser_->
      RegisterRtpHeaderExtension(webrtc::kRtpExtensionAudioLevel,
                                 kAudioLevelHeaderId);

  local_voe_ = webrtc::VoiceEngine::Create();
  local_base_ = webrtc::VoEBase::GetInterface(local_voe_);
  local_network_ = webrtc::VoENetwork::GetInterface(local_voe_);
  local_rtp_rtcp_ = webrtc::VoERTP_RTCP::GetInterface(local_voe_);

  // In principle, we can use one VoiceEngine to achieve the same goal. Well, in
  // here, we use two engines to make it more like reality.
  remote_voe_ = webrtc::VoiceEngine::Create();
  remote_base_ = webrtc::VoEBase::GetInterface(remote_voe_);
  remote_codec_ = webrtc::VoECodec::GetInterface(remote_voe_);
  remote_network_ = webrtc::VoENetwork::GetInterface(remote_voe_);
  remote_rtp_rtcp_ = webrtc::VoERTP_RTCP::GetInterface(remote_voe_);
  remote_file_ = webrtc::VoEFile::GetInterface(remote_voe_);

  EXPECT_EQ(0, local_base_->Init());
  local_sender_ = local_base_->CreateChannel();
  EXPECT_EQ(0, local_network_->RegisterExternalTransport(local_sender_, *this));
  EXPECT_EQ(0, local_rtp_rtcp_->SetLocalSSRC(local_sender_, kLocalSsrc));
  EXPECT_EQ(0, local_rtp_rtcp_->
      SetSendAudioLevelIndicationStatus(local_sender_, true,
                                        kAudioLevelHeaderId));

  EXPECT_EQ(0, local_base_->StartSend(local_sender_));

  EXPECT_EQ(0, remote_base_->Init());
  reflector_ = remote_base_->CreateChannel();
  EXPECT_EQ(0, remote_network_->RegisterExternalTransport(reflector_, *this));
  EXPECT_EQ(0, remote_rtp_rtcp_->SetLocalSSRC(reflector_, kReflectorSsrc));

  thread_->Start();
  thread_->SetPriority(webrtc::kHighPriority);
}

ConferenceTransport::~ConferenceTransport() {
  // Must stop sending, otherwise DispatchPackets() cannot quit.
  EXPECT_EQ(0, remote_network_->DeRegisterExternalTransport(reflector_));
  EXPECT_EQ(0, local_network_->DeRegisterExternalTransport(local_sender_));

  while (!streams_.empty()) {
    auto stream = streams_.begin();
    RemoveStream(stream->first);
  }

  EXPECT_TRUE(thread_->Stop());

  remote_file_->Release();
  remote_rtp_rtcp_->Release();
  remote_network_->Release();
  remote_base_->Release();

  local_rtp_rtcp_->Release();
  local_network_->Release();
  local_base_->Release();

  EXPECT_TRUE(webrtc::VoiceEngine::Delete(remote_voe_));
  EXPECT_TRUE(webrtc::VoiceEngine::Delete(local_voe_));
}

bool ConferenceTransport::SendRtp(const uint8_t* data,
                                  size_t len,
                                  const webrtc::PacketOptions& options) {
  StorePacket(Packet::Rtp, data, len);
  return true;
}

bool ConferenceTransport::SendRtcp(const uint8_t* data, size_t len) {
  StorePacket(Packet::Rtcp, data, len);
  return true;
}

int ConferenceTransport::GetReceiverChannelForSsrc(unsigned int sender_ssrc)
    const {
  webrtc::CriticalSectionScoped lock(stream_crit_.get());
  auto it = streams_.find(sender_ssrc);
  if (it != streams_.end()) {
    return it->second.second;
  }
  return -1;
}

void ConferenceTransport::StorePacket(Packet::Type type,
                                      const void* data,
                                      size_t len) {
  {
    webrtc::CriticalSectionScoped lock(pq_crit_.get());
    packet_queue_.push_back(Packet(type, data, len, rtc::Time()));
  }
  packet_event_->Set();
}

// This simulates the flow of RTP and RTCP packets. Complications like that
// a packet is first sent to the reflector, and then forwarded to the receiver
// are simplified, in this particular case, to a direct link between the sender
// and the receiver.
void ConferenceTransport::SendPacket(const Packet& packet) {
  int destination = -1;

  switch (packet.type_) {
    case Packet::Rtp: {
      webrtc::RTPHeader rtp_header;
      rtp_header_parser_->Parse(packet.data_, packet.len_, &rtp_header);
      if (rtp_header.ssrc == kLocalSsrc) {
        remote_network_->ReceivedRTPPacket(reflector_, packet.data_,
                                           packet.len_, webrtc::PacketTime());
      } else {
        if (loudest_filter_.ForwardThisPacket(rtp_header)) {
          destination = GetReceiverChannelForSsrc(rtp_header.ssrc);
          if (destination != -1) {
            local_network_->ReceivedRTPPacket(destination, packet.data_,
                                              packet.len_,
                                              webrtc::PacketTime());
          }
        }
      }
      break;
    }
    case Packet::Rtcp: {
      unsigned int sender_ssrc = ParseRtcpSsrc(packet.data_, packet.len_);
      if (sender_ssrc == kLocalSsrc) {
        remote_network_->ReceivedRTCPPacket(reflector_, packet.data_,
                                            packet.len_);
      } else if (sender_ssrc == kReflectorSsrc) {
        local_network_->ReceivedRTCPPacket(local_sender_, packet.data_,
                                           packet.len_);
      } else {
        destination = GetReceiverChannelForSsrc(sender_ssrc);
        if (destination != -1) {
          local_network_->ReceivedRTCPPacket(destination, packet.data_,
                                             packet.len_);
        }
      }
      break;
    }
  }
}

bool ConferenceTransport::DispatchPackets() {
  switch (packet_event_->Wait(1000)) {
    case webrtc::kEventSignaled:
      break;
    case webrtc::kEventTimeout:
      return true;
    case webrtc::kEventError:
      ADD_FAILURE() << "kEventError encountered.";
      return true;
  }

  while (true) {
    Packet packet;
    {
      webrtc::CriticalSectionScoped lock(pq_crit_.get());
      if (packet_queue_.empty())
        break;
      packet = packet_queue_.front();
      packet_queue_.pop_front();
    }

    int32_t elapsed_time_ms = rtc::TimeSince(packet.send_time_ms_);
    int32_t sleep_ms = rtt_ms_ / 2 - elapsed_time_ms;
    if (sleep_ms > 0) {
      // Every packet should be delayed by half of RTT.
      webrtc::SleepMs(sleep_ms);
    }

    SendPacket(packet);
  }
  return true;
}

void ConferenceTransport::SetRtt(unsigned int rtt_ms) {
  rtt_ms_ = rtt_ms;
}

unsigned int ConferenceTransport::AddStream(std::string file_name,
                                            webrtc::FileFormats format) {
  const int new_sender = remote_base_->CreateChannel();
  EXPECT_EQ(0, remote_network_->RegisterExternalTransport(new_sender, *this));

  const unsigned int remote_ssrc = kFirstRemoteSsrc + stream_count_++;
  EXPECT_EQ(0, remote_rtp_rtcp_->SetLocalSSRC(new_sender, remote_ssrc));
  EXPECT_EQ(0, remote_rtp_rtcp_->
      SetSendAudioLevelIndicationStatus(new_sender, true, kAudioLevelHeaderId));

  EXPECT_EQ(0, remote_codec_->SetSendCodec(new_sender, kCodecInst));
  EXPECT_EQ(0, remote_base_->StartSend(new_sender));
  EXPECT_EQ(0, remote_file_->StartPlayingFileAsMicrophone(
      new_sender, file_name.c_str(), true, false, format, 1.0));

  const int new_receiver = local_base_->CreateChannel();
  EXPECT_EQ(0, local_base_->AssociateSendChannel(new_receiver, local_sender_));

  EXPECT_EQ(0, local_network_->RegisterExternalTransport(new_receiver, *this));
  // Receive channels have to have the same SSRC in order to send receiver
  // reports with this SSRC.
  EXPECT_EQ(0, local_rtp_rtcp_->SetLocalSSRC(new_receiver, kLocalSsrc));

  {
    webrtc::CriticalSectionScoped lock(stream_crit_.get());
    streams_[remote_ssrc] = std::make_pair(new_sender, new_receiver);
  }
  return remote_ssrc;  // remote ssrc used as stream id.
}

bool ConferenceTransport::RemoveStream(unsigned int id) {
  webrtc::CriticalSectionScoped lock(stream_crit_.get());
  auto it = streams_.find(id);
  if (it == streams_.end()) {
    return false;
  }
  EXPECT_EQ(0, remote_network_->
      DeRegisterExternalTransport(it->second.second));
  EXPECT_EQ(0, local_network_->
      DeRegisterExternalTransport(it->second.first));
  EXPECT_EQ(0, remote_base_->DeleteChannel(it->second.second));
  EXPECT_EQ(0, local_base_->DeleteChannel(it->second.first));
  streams_.erase(it);
  return true;
}

bool ConferenceTransport::StartPlayout(unsigned int id) {
  int dst = GetReceiverChannelForSsrc(id);
  if (dst == -1) {
    return false;
  }
  EXPECT_EQ(0, local_base_->StartPlayout(dst));
  return true;
}

bool ConferenceTransport::GetReceiverStatistics(unsigned int id,
                                                webrtc::CallStatistics* stats) {
  int dst = GetReceiverChannelForSsrc(id);
  if (dst == -1) {
    return false;
  }
  EXPECT_EQ(0, local_rtp_rtcp_->GetRTCPStatistics(dst, *stats));
  return true;
}
}  // namespace voetest
