/*
 *  Copyright (c) 2017 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 "audio/test/audio_bwe_integration_test.h"

#include "absl/memory/memory.h"
#include "call/fake_network_pipe.h"
#include "call/simulated_network.h"
#include "common_audio/wav_file.h"
#include "system_wrappers/include/sleep.h"
#include "test/field_trial.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"

namespace webrtc {
namespace test {

namespace {
// Wait a second between stopping sending and stopping receiving audio.
constexpr int kExtraProcessTimeMs = 1000;
}  // namespace

AudioBweTest::AudioBweTest() : EndToEndTest(CallTest::kDefaultTimeoutMs) {}

size_t AudioBweTest::GetNumVideoStreams() const {
  return 0;
}
size_t AudioBweTest::GetNumAudioStreams() const {
  return 1;
}
size_t AudioBweTest::GetNumFlexfecStreams() const {
  return 0;
}

std::unique_ptr<TestAudioDeviceModule::Capturer>
AudioBweTest::CreateCapturer() {
  return TestAudioDeviceModule::CreateWavFileReader(AudioInputFile());
}

void AudioBweTest::OnFakeAudioDevicesCreated(
    TestAudioDeviceModule* send_audio_device,
    TestAudioDeviceModule* recv_audio_device) {
  send_audio_device_ = send_audio_device;
}

test::PacketTransport* AudioBweTest::CreateSendTransport(
    SingleThreadedTaskQueueForTesting* task_queue,
    Call* sender_call) {
  return new test::PacketTransport(
      task_queue, sender_call, this, test::PacketTransport::kSender,
      test::CallTest::payload_type_map_,
      absl::make_unique<FakeNetworkPipe>(
          Clock::GetRealTimeClock(),
          absl::make_unique<SimulatedNetwork>(GetNetworkPipeConfig())));
}

test::PacketTransport* AudioBweTest::CreateReceiveTransport(
    SingleThreadedTaskQueueForTesting* task_queue) {
  return new test::PacketTransport(
      task_queue, nullptr, this, test::PacketTransport::kReceiver,
      test::CallTest::payload_type_map_,
      absl::make_unique<FakeNetworkPipe>(
          Clock::GetRealTimeClock(),
          absl::make_unique<SimulatedNetwork>(GetNetworkPipeConfig())));
}

void AudioBweTest::PerformTest() {
  send_audio_device_->WaitForRecordingEnd();
  SleepMs(GetNetworkPipeConfig().queue_delay_ms + kExtraProcessTimeMs);
}

class StatsPollTask : public rtc::QueuedTask {
 public:
  explicit StatsPollTask(Call* sender_call) : sender_call_(sender_call) {}

 private:
  bool Run() override {
    RTC_CHECK(sender_call_);
    Call::Stats call_stats = sender_call_->GetStats();
    EXPECT_GT(call_stats.send_bandwidth_bps, 25000);
    rtc::TaskQueue::Current()->PostDelayedTask(
        std::unique_ptr<QueuedTask>(this), 100);
    return false;
  }
  Call* sender_call_;
};

class NoBandwidthDropAfterDtx : public AudioBweTest {
 public:
  NoBandwidthDropAfterDtx()
      : sender_call_(nullptr), stats_poller_("stats poller task queue") {}

  void ModifyAudioConfigs(
      AudioSendStream::Config* send_config,
      std::vector<AudioReceiveStream::Config>* receive_configs) override {
    send_config->send_codec_spec = AudioSendStream::Config::SendCodecSpec(
        test::CallTest::kAudioSendPayloadType,
        {"OPUS",
         48000,
         2,
         {{"ptime", "60"}, {"usedtx", "1"}, {"stereo", "1"}}});

    send_config->min_bitrate_bps = 6000;
    send_config->max_bitrate_bps = 100000;
    send_config->rtp.extensions.push_back(
        RtpExtension(RtpExtension::kTransportSequenceNumberUri,
                     kTransportSequenceNumberExtensionId));
    for (AudioReceiveStream::Config& recv_config : *receive_configs) {
      recv_config.rtp.transport_cc = true;
      recv_config.rtp.extensions = send_config->rtp.extensions;
      recv_config.rtp.remote_ssrc = send_config->rtp.ssrc;
    }
  }

  std::string AudioInputFile() override {
    return test::ResourcePath("voice_engine/audio_dtx16", "wav");
  }

  DefaultNetworkSimulationConfig GetNetworkPipeConfig() override {
    DefaultNetworkSimulationConfig pipe_config;
    pipe_config.link_capacity_kbps = 50;
    pipe_config.queue_length_packets = 1500;
    pipe_config.queue_delay_ms = 300;
    return pipe_config;
  }

  void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
    sender_call_ = sender_call;
  }

  void PerformTest() override {
    stats_poller_.PostDelayedTask(
        std::unique_ptr<rtc::QueuedTask>(new StatsPollTask(sender_call_)), 100);
    sender_call_->OnTransportOverheadChanged(webrtc::MediaType::AUDIO, 0);
    AudioBweTest::PerformTest();
  }

 private:
  Call* sender_call_;
  rtc::TaskQueue stats_poller_;
};

using AudioBweIntegrationTest = CallTest;

// TODO(tschumim): This test is flaky when run on android and mac. Re-enable the
// test for when the issue is fixed.
TEST_F(AudioBweIntegrationTest, DISABLED_NoBandwidthDropAfterDtx) {
  webrtc::test::ScopedFieldTrials override_field_trials(
      "WebRTC-Audio-SendSideBwe/Enabled/"
      "WebRTC-SendSideBwe-WithOverhead/Enabled/");
  NoBandwidthDropAfterDtx test;
  RunBaseTest(&test);
}

}  // namespace test
}  // namespace webrtc
