/*
 *  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 "webrtc/audio/test/audio_bwe_integration_test.h"

#include "webrtc/common_audio/wav_file.h"
#include "webrtc/rtc_base/ptr_util.h"
#include "webrtc/system_wrappers/include/sleep.h"
#include "webrtc/test/field_trial.h"
#include "webrtc/test/gtest.h"
#include "webrtc/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<test::FakeAudioDevice::Capturer>
AudioBweTest::CreateCapturer() {
  return test::FakeAudioDevice::CreateWavFileReader(AudioInputFile());
}

void AudioBweTest::OnFakeAudioDevicesCreated(
    test::FakeAudioDevice* send_audio_device,
    test::FakeAudioDevice* 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_, GetNetworkPipeConfig());
}

test::PacketTransport* AudioBweTest::CreateReceiveTransport(
    SingleThreadedTaskQueueForTesting* task_queue) {
  return new test::PacketTransport(
      task_queue, nullptr, this, test::PacketTransport::kReceiver,
      test::CallTest::payload_type_map_, 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 =
        rtc::Optional<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");
  }

  FakeNetworkPipe::Config GetNetworkPipeConfig() override {
    FakeNetworkPipe::Config 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
