/*
 *  Copyright (c) 2013 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 <assert.h>
#include <math.h>
#include <string.h>

#include <iostream>
#include <memory>

#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "common_types.h"  // NOLINT(build/include)
#include "modules/audio_coding/codecs/audio_format_conversion.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
#include "modules/audio_coding/test/Channel.h"
#include "modules/audio_coding/test/PCMFile.h"
#include "modules/audio_coding/test/utility.h"
#include "rtc_base/flags.h"
#include "rtc_base/strings/string_builder.h"
#include "system_wrappers/include/event_wrapper.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"

DEFINE_string(codec, "isac", "Codec Name");
DEFINE_int(sample_rate_hz, 16000, "Sampling rate in Hertz.");
DEFINE_int(num_channels, 1, "Number of Channels.");
DEFINE_string(input_file, "", "Input file, PCM16 32 kHz, optional.");
DEFINE_int(delay, 0, "Delay in millisecond.");
DEFINE_bool(dtx, false, "Enable DTX at the sender side.");
DEFINE_bool(packet_loss, false, "Apply packet loss, c.f. Channel{.cc, .h}.");
DEFINE_bool(fec, false, "Use Forward Error Correction (FEC).");
DEFINE_bool(help, false, "Print this message.");

namespace webrtc {

namespace {

struct CodecSettings {
  char name[50];
  int sample_rate_hz;
  int num_channels;
};

struct AcmSettings {
  bool dtx;
  bool fec;
};

struct TestSettings {
  CodecSettings codec;
  AcmSettings acm;
  bool packet_loss;
};

}  // namespace

class DelayTest {
 public:
  DelayTest()
      : acm_a_(AudioCodingModule::Create(
            AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
        acm_b_(AudioCodingModule::Create(
            AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
        channel_a2b_(new Channel),
        test_cntr_(0),
        encoding_sample_rate_hz_(8000) {}

  ~DelayTest() {
    if (channel_a2b_ != NULL) {
      delete channel_a2b_;
      channel_a2b_ = NULL;
    }
    in_file_a_.Close();
  }

  void Initialize() {
    test_cntr_ = 0;
    std::string file_name =
        webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
    if (strlen(FLAG_input_file) > 0)
      file_name = FLAG_input_file;
    in_file_a_.Open(file_name, 32000, "rb");
    ASSERT_EQ(0, acm_a_->InitializeReceiver())
        << "Couldn't initialize receiver.\n";
    ASSERT_EQ(0, acm_b_->InitializeReceiver())
        << "Couldn't initialize receiver.\n";

    if (FLAG_delay > 0) {
      ASSERT_EQ(0, acm_b_->SetMinimumPlayoutDelay(FLAG_delay))
          << "Failed to set minimum delay.\n";
    }

    int num_encoders = acm_a_->NumberOfCodecs();
    CodecInst my_codec_param;
    for (int n = 0; n < num_encoders; n++) {
      EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param)) << "Failed to get codec.";
      if (STR_CASE_CMP(my_codec_param.plname, "opus") == 0)
        my_codec_param.channels = 1;
      else if (my_codec_param.channels > 1)
        continue;
      if (STR_CASE_CMP(my_codec_param.plname, "CN") == 0 &&
          my_codec_param.plfreq == 48000)
        continue;
      if (STR_CASE_CMP(my_codec_param.plname, "telephone-event") == 0)
        continue;
      ASSERT_EQ(true,
                acm_b_->RegisterReceiveCodec(my_codec_param.pltype,
                                             CodecInstToSdp(my_codec_param)));
    }

    // Create and connect the channel
    ASSERT_EQ(0, acm_a_->RegisterTransportCallback(channel_a2b_))
        << "Couldn't register Transport callback.\n";
    channel_a2b_->RegisterReceiverACM(acm_b_.get());
  }

  void Perform(const TestSettings* config,
               size_t num_tests,
               int duration_sec,
               const char* output_prefix) {
    for (size_t n = 0; n < num_tests; ++n) {
      ApplyConfig(config[n]);
      Run(duration_sec, output_prefix);
    }
  }

 private:
  void ApplyConfig(const TestSettings& config) {
    printf("====================================\n");
    printf(
        "Test %d \n"
        "Codec: %s, %d kHz, %d channel(s)\n"
        "ACM: DTX %s, FEC %s\n"
        "Channel: %s\n",
        ++test_cntr_, config.codec.name, config.codec.sample_rate_hz,
        config.codec.num_channels, config.acm.dtx ? "on" : "off",
        config.acm.fec ? "on" : "off",
        config.packet_loss ? "with packet-loss" : "no packet-loss");
    SendCodec(config.codec);
    ConfigAcm(config.acm);
    ConfigChannel(config.packet_loss);
  }

  void SendCodec(const CodecSettings& config) {
    CodecInst my_codec_param;
    ASSERT_EQ(
        0, AudioCodingModule::Codec(config.name, &my_codec_param,
                                    config.sample_rate_hz, config.num_channels))
        << "Specified codec is not supported.\n";

    encoding_sample_rate_hz_ = my_codec_param.plfreq;
    ASSERT_EQ(0, acm_a_->RegisterSendCodec(my_codec_param))
        << "Failed to register send-codec.\n";
  }

  void ConfigAcm(const AcmSettings& config) {
    ASSERT_EQ(0, acm_a_->SetVAD(config.dtx, config.dtx, VADAggr))
        << "Failed to set VAD.\n";
    ASSERT_EQ(0, acm_a_->SetREDStatus(config.fec)) << "Failed to set RED.\n";
  }

  void ConfigChannel(bool packet_loss) {
    channel_a2b_->SetFECTestWithPacketLoss(packet_loss);
  }

  void OpenOutFile(const char* output_id) {
    rtc::StringBuilder file_stream;
    file_stream << "delay_test_" << FLAG_codec << "_" << FLAG_sample_rate_hz
                << "Hz"
                << "_" << FLAG_delay << "ms.pcm";
    std::cout << "Output file: " << file_stream.str() << std::endl << std::endl;
    std::string file_name = webrtc::test::OutputPath() + file_stream.str();
    out_file_b_.Open(file_name.c_str(), 32000, "wb");
  }

  void Run(int duration_sec, const char* output_prefix) {
    OpenOutFile(output_prefix);
    AudioFrame audio_frame;
    uint32_t out_freq_hz_b = out_file_b_.SamplingFrequency();

    int num_frames = 0;
    int in_file_frames = 0;
    uint32_t received_ts;
    double average_delay = 0;
    double inst_delay_sec = 0;
    while (num_frames < (duration_sec * 100)) {
      if (in_file_a_.EndOfFile()) {
        in_file_a_.Rewind();
      }

      // Print delay information every 16 frame
      if ((num_frames & 0x3F) == 0x3F) {
        NetworkStatistics statistics;
        acm_b_->GetNetworkStatistics(&statistics);
        fprintf(stdout,
                "delay: min=%3d  max=%3d  mean=%3d  median=%3d"
                " ts-based average = %6.3f, "
                "curr buff-lev = %4u opt buff-lev = %4u \n",
                statistics.minWaitingTimeMs, statistics.maxWaitingTimeMs,
                statistics.meanWaitingTimeMs, statistics.medianWaitingTimeMs,
                average_delay, statistics.currentBufferSize,
                statistics.preferredBufferSize);
        fflush(stdout);
      }

      in_file_a_.Read10MsData(audio_frame);
      ASSERT_GE(acm_a_->Add10MsData(audio_frame), 0);
      bool muted;
      ASSERT_EQ(0,
                acm_b_->PlayoutData10Ms(out_freq_hz_b, &audio_frame, &muted));
      RTC_DCHECK(!muted);
      out_file_b_.Write10MsData(
          audio_frame.data(),
          audio_frame.samples_per_channel_ * audio_frame.num_channels_);
      received_ts = channel_a2b_->LastInTimestamp();
      absl::optional<uint32_t> playout_timestamp = acm_b_->PlayoutTimestamp();
      ASSERT_TRUE(playout_timestamp);
      inst_delay_sec = static_cast<uint32_t>(received_ts - *playout_timestamp) /
                       static_cast<double>(encoding_sample_rate_hz_);

      if (num_frames > 10)
        average_delay = 0.95 * average_delay + 0.05 * inst_delay_sec;

      ++num_frames;
      ++in_file_frames;
    }
    out_file_b_.Close();
  }

  std::unique_ptr<AudioCodingModule> acm_a_;
  std::unique_ptr<AudioCodingModule> acm_b_;

  Channel* channel_a2b_;

  PCMFile in_file_a_;
  PCMFile out_file_b_;
  int test_cntr_;
  int encoding_sample_rate_hz_;
};

}  // namespace webrtc

int main(int argc, char* argv[]) {
  if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true)) {
    return 1;
  }
  if (FLAG_help) {
    rtc::FlagList::Print(nullptr, false);
    return 0;
  }

  webrtc::TestSettings test_setting;
  strcpy(test_setting.codec.name, FLAG_codec);

  if (FLAG_sample_rate_hz != 8000 && FLAG_sample_rate_hz != 16000 &&
      FLAG_sample_rate_hz != 32000 && FLAG_sample_rate_hz != 48000) {
    std::cout << "Invalid sampling rate.\n";
    return 1;
  }
  test_setting.codec.sample_rate_hz = FLAG_sample_rate_hz;
  if (FLAG_num_channels < 1 || FLAG_num_channels > 2) {
    std::cout << "Only mono and stereo are supported.\n";
    return 1;
  }
  test_setting.codec.num_channels = FLAG_num_channels;
  test_setting.acm.dtx = FLAG_dtx;
  test_setting.acm.fec = FLAG_fec;
  test_setting.packet_loss = FLAG_packet_loss;

  webrtc::DelayTest delay_test;
  delay_test.Initialize();
  delay_test.Perform(&test_setting, 1, 240, "delay_test");
  return 0;
}
