/*
 *  Copyright (c) 2014 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 "modules/audio_coding/codecs/opus/opus_inst.h"
#include "modules/audio_coding/codecs/opus/opus_interface.h"
#include "modules/audio_coding/neteq/tools/neteq_quality_test.h"
#include "rtc_base/flags.h"

using ::testing::InitGoogleTest;

namespace webrtc {
namespace test {
namespace {

static const int kOpusBlockDurationMs = 20;
static const int kOpusSamplingKhz = 48;

WEBRTC_DEFINE_int(bit_rate_kbps, 32, "Target bit rate (kbps).");

WEBRTC_DEFINE_int(complexity,
                  10,
                  "Complexity: 0 ~ 10 -- defined as in Opus"
                  "specification.");

WEBRTC_DEFINE_int(maxplaybackrate, 48000, "Maximum playback rate (Hz).");

WEBRTC_DEFINE_int(application, 0, "Application mode: 0 -- VOIP, 1 -- Audio.");

WEBRTC_DEFINE_int(reported_loss_rate,
                  10,
                  "Reported percentile of packet loss.");

WEBRTC_DEFINE_bool(fec, false, "Enable FEC for encoding (-nofec to disable).");

WEBRTC_DEFINE_bool(dtx, false, "Enable DTX for encoding (-nodtx to disable).");

WEBRTC_DEFINE_int(sub_packets, 1, "Number of sub packets to repacketize.");

}  // namespace

class NetEqOpusQualityTest : public NetEqQualityTest {
 protected:
  NetEqOpusQualityTest();
  void SetUp() override;
  void TearDown() override;
  int EncodeBlock(int16_t* in_data,
                  size_t block_size_samples,
                  rtc::Buffer* payload,
                  size_t max_bytes) override;

 private:
  WebRtcOpusEncInst* opus_encoder_;
  OpusRepacketizer* repacketizer_;
  size_t sub_block_size_samples_;
  int bit_rate_kbps_;
  bool fec_;
  bool dtx_;
  int complexity_;
  int maxplaybackrate_;
  int target_loss_rate_;
  int sub_packets_;
  int application_;
};

NetEqOpusQualityTest::NetEqOpusQualityTest()
    : NetEqQualityTest(kOpusBlockDurationMs * FLAG_sub_packets,
                       kOpusSamplingKhz,
                       kOpusSamplingKhz,
                       SdpAudioFormat("opus", 48000, 2)),
      opus_encoder_(NULL),
      repacketizer_(NULL),
      sub_block_size_samples_(
          static_cast<size_t>(kOpusBlockDurationMs * kOpusSamplingKhz)),
      bit_rate_kbps_(FLAG_bit_rate_kbps),
      fec_(FLAG_fec),
      dtx_(FLAG_dtx),
      complexity_(FLAG_complexity),
      maxplaybackrate_(FLAG_maxplaybackrate),
      target_loss_rate_(FLAG_reported_loss_rate),
      sub_packets_(FLAG_sub_packets) {
  // Flag validation
  RTC_CHECK(FLAG_bit_rate_kbps >= 6 && FLAG_bit_rate_kbps <= 510)
      << "Invalid bit rate, should be between 6 and 510 kbps.";

  RTC_CHECK(FLAG_complexity >= -1 && FLAG_complexity <= 10)
      << "Invalid complexity setting, should be between 0 and 10.";

  RTC_CHECK(FLAG_application == 0 || FLAG_application == 1)
      << "Invalid application mode, should be 0 or 1.";

  RTC_CHECK(FLAG_reported_loss_rate >= 0 && FLAG_reported_loss_rate <= 100)
      << "Invalid packet loss percentile, should be between 0 and 100.";

  RTC_CHECK(FLAG_sub_packets >= 1 && FLAG_sub_packets <= 3)
      << "Invalid number of sub packets, should be between 1 and 3.";

  // Redefine decoder type if input is stereo.
  if (channels_ > 1) {
    audio_format_ = SdpAudioFormat(
        "opus", 48000, 2, std::map<std::string, std::string>{{"stereo", "1"}});
  }
  application_ = FLAG_application;
}

void NetEqOpusQualityTest::SetUp() {
  // Create encoder memory.
  WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, application_, 48000);
  ASSERT_TRUE(opus_encoder_);

  // Create repacketizer.
  repacketizer_ = opus_repacketizer_create();
  ASSERT_TRUE(repacketizer_);

  // Set bitrate.
  EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, bit_rate_kbps_ * 1000));
  if (fec_) {
    EXPECT_EQ(0, WebRtcOpus_EnableFec(opus_encoder_));
  }
  if (dtx_) {
    EXPECT_EQ(0, WebRtcOpus_EnableDtx(opus_encoder_));
  }
  EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_encoder_, complexity_));
  EXPECT_EQ(0, WebRtcOpus_SetMaxPlaybackRate(opus_encoder_, maxplaybackrate_));
  EXPECT_EQ(0, WebRtcOpus_SetPacketLossRate(opus_encoder_, target_loss_rate_));
  NetEqQualityTest::SetUp();
}

void NetEqOpusQualityTest::TearDown() {
  // Free memory.
  EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
  opus_repacketizer_destroy(repacketizer_);
  NetEqQualityTest::TearDown();
}

int NetEqOpusQualityTest::EncodeBlock(int16_t* in_data,
                                      size_t block_size_samples,
                                      rtc::Buffer* payload,
                                      size_t max_bytes) {
  EXPECT_EQ(block_size_samples, sub_block_size_samples_ * sub_packets_);
  int16_t* pointer = in_data;
  int value;
  opus_repacketizer_init(repacketizer_);
  for (int idx = 0; idx < sub_packets_; idx++) {
    payload->AppendData(max_bytes, [&](rtc::ArrayView<uint8_t> payload) {
      value = WebRtcOpus_Encode(opus_encoder_, pointer, sub_block_size_samples_,
                                max_bytes, payload.data());

      Log() << "Encoded a frame with Opus mode "
            << (value == 0 ? 0 : payload[0] >> 3) << std::endl;

      return (value >= 0) ? static_cast<size_t>(value) : 0;
    });

    if (OPUS_OK !=
        opus_repacketizer_cat(repacketizer_, payload->data(), value)) {
      opus_repacketizer_init(repacketizer_);
      // If the repacketization fails, we discard this frame.
      return 0;
    }
    pointer += sub_block_size_samples_ * channels_;
  }
  value = opus_repacketizer_out(repacketizer_, payload->data(),
                                static_cast<opus_int32>(max_bytes));
  EXPECT_GE(value, 0);
  return value;
}

TEST_F(NetEqOpusQualityTest, Test) {
  Simulate();
}

}  // namespace test
}  // namespace webrtc
