/*
 *  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 "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"

#include <assert.h>
#include <math.h>

#include <iostream>

#include "gflags/gflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/common_types.h"
#include "webrtc/engine_configurations.h"
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
#include "webrtc/modules/audio_coding/main/source/acm_common_defs.h"
#include "webrtc/modules/audio_coding/main/test/Channel.h"
#include "webrtc/modules/audio_coding/main/test/PCMFile.h"
#include "webrtc/modules/audio_coding/main/test/utility.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/test/testsupport/fileutils.h"

DEFINE_string(codec, "isac", "Codec Name");
DEFINE_int32(sample_rate_hz, 16000, "Sampling rate in Hertz.");
DEFINE_int32(num_channels, 1, "Number of Channels.");
DEFINE_string(input_file, "", "Input file, PCM16 32 kHz, optional.");
DEFINE_int32(delay, 0, "Delay in millisecond.");
DEFINE_int32(init_delay, 0, "Initial delay in millisecond.");
DEFINE_bool(dtx, false, "Enable DTX at the sender side.");

namespace webrtc {
namespace {

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

struct AcmConfig {
  bool dtx;
  bool fec;
};

struct Config {
  CodecConfig codec;
  AcmConfig acm;
  bool packet_loss;
};


class DelayTest {
 public:

  DelayTest()
      : acm_a_(AudioCodingModule::Create(0)),
        acm_b_(AudioCodingModule::Create(1)),
        channel_a2b_(NULL),
        test_cntr_(0),
        encoding_sample_rate_hz_(8000) {}

  ~DelayTest() {}

  void TearDown() {
    if (channel_a2b_ != NULL) {
      delete channel_a2b_;
      channel_a2b_ = NULL;
    }
  }

  void SetUp() {
    test_cntr_ = 0;
    std::string file_name = webrtc::test::ResourcePath(
        "audio_coding/testfile32kHz", "pcm");
    if (FLAGS_input_file.size() > 0)
      file_name = FLAGS_input_file;
    in_file_a_.Open(file_name, 32000, "rb");
    acm_a_->InitializeReceiver();
    acm_b_->InitializeReceiver();
    if (FLAGS_init_delay > 0) {
      ASSERT_EQ(0, acm_b_->SetInitialPlayoutDelay(FLAGS_init_delay));
    }

    if (FLAGS_delay > 0) {
      ASSERT_EQ(0, acm_b_->SetMinimumPlayoutDelay(FLAGS_delay));
    }

    uint8_t num_encoders = acm_a_->NumberOfCodecs();
    CodecInst my_codec_param;
    for (int n = 0; n < num_encoders; n++) {
      acm_b_->Codec(n, &my_codec_param);
      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;
      acm_b_->RegisterReceiveCodec(my_codec_param);
    }

    // Create and connect the channel
    channel_a2b_ = new Channel;
    acm_a_->RegisterTransportCallback(channel_a2b_);
    channel_a2b_->RegisterReceiverACM(acm_b_.get());
  }

  void Perform(const Config* 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 Config& 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 CodecConfig& config) {
    CodecInst my_codec_param;
    ASSERT_EQ(
        0,
        AudioCodingModule::Codec(config.name, &my_codec_param,
                                 config.sample_rate_hz, config.num_channels));
    encoding_sample_rate_hz_ = my_codec_param.plfreq;
    ASSERT_EQ(0, acm_a_->RegisterSendCodec(my_codec_param));
  }

  void ConfigAcm(const AcmConfig& config) {
    ASSERT_EQ(0, acm_a_->SetVAD(config.dtx, config.dtx, VADAggr));
    ASSERT_EQ(0, acm_a_->SetFECStatus(config.fec));
  }

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

  void OpenOutFile(const char* output_id) {
    std::stringstream file_stream;
    file_stream << "delay_test_" << FLAGS_codec << "_" << FLAGS_sample_rate_hz
        << "Hz" << "_" << FLAGS_init_delay << "ms_" << FLAGS_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 playout_ts;
    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) {
        ACMNetworkStatistics statistics;
        acm_b_->NetworkStatistics(&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_EQ(0, acm_a_->Add10MsData(audio_frame));
      ASSERT_LE(0, acm_a_->Process());
      ASSERT_EQ(0, acm_b_->PlayoutData10Ms(out_freq_hz_b, &audio_frame));
      out_file_b_.Write10MsData(
          audio_frame.data_,
          audio_frame.samples_per_channel_ * audio_frame.num_channels_);
      acm_b_->PlayoutTimestamp(&playout_ts);
      received_ts = channel_a2b_->LastInTimestamp();
      inst_delay_sec = static_cast<uint32_t>(received_ts - playout_ts)
          / 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();
  }

  scoped_ptr<AudioCodingModule> acm_a_;
  scoped_ptr<AudioCodingModule> acm_b_;

  Channel* channel_a2b_;

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

void RunTest() {
  Config config;
  strcpy(config.codec.name, FLAGS_codec.c_str());
  config.codec.sample_rate_hz = FLAGS_sample_rate_hz;
  config.codec.num_channels = FLAGS_num_channels;
  config.acm.dtx = FLAGS_dtx;
  config.acm.fec = false;
  config.packet_loss = false;

  DelayTest delay_test;
  delay_test.SetUp();
  delay_test.Perform(&config, 1, 240, "delay_test");
  delay_test.TearDown();
}
}  // namespace
}  // namespace webrtc
