/*
 *  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 <memory>

#include "modules/audio_coding/codecs/opus/opus_interface.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

using std::get;
using std::string;
using std::tuple;
using ::testing::TestWithParam;

namespace webrtc {

// Define coding parameter as <channels, bit_rate, filename, extension>.
typedef tuple<size_t, int, string, string> coding_param;
typedef struct mode mode;

struct mode {
  bool fec;
  uint8_t target_packet_loss_rate;
};

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

class OpusFecTest : public TestWithParam<coding_param> {
 protected:
  OpusFecTest();

  void SetUp() override;
  void TearDown() override;

  virtual void EncodeABlock();

  virtual void DecodeABlock(bool lost_previous, bool lost_current);

  int block_duration_ms_;
  int sampling_khz_;
  size_t block_length_sample_;

  size_t channels_;
  int bit_rate_;

  size_t data_pointer_;
  size_t loop_length_samples_;
  size_t max_bytes_;
  size_t encoded_bytes_;

  WebRtcOpusEncInst* opus_encoder_;
  WebRtcOpusDecInst* opus_decoder_;

  string in_filename_;

  std::unique_ptr<int16_t[]> in_data_;
  std::unique_ptr<int16_t[]> out_data_;
  std::unique_ptr<uint8_t[]> bit_stream_;
};

void OpusFecTest::SetUp() {
  channels_ = get<0>(GetParam());
  bit_rate_ = get<1>(GetParam());
  printf("Coding %zu channel signal at %d bps.\n", channels_, bit_rate_);

  in_filename_ = test::ResourcePath(get<2>(GetParam()), get<3>(GetParam()));

  FILE* fp = fopen(in_filename_.c_str(), "rb");
  ASSERT_FALSE(fp == NULL);

  // Obtain file size.
  fseek(fp, 0, SEEK_END);
  loop_length_samples_ = ftell(fp) / sizeof(int16_t);
  rewind(fp);

  // Allocate memory to contain the whole file.
  in_data_.reset(
      new int16_t[loop_length_samples_ + block_length_sample_ * channels_]);

  // Copy the file into the buffer.
  ASSERT_EQ(fread(&in_data_[0], sizeof(int16_t), loop_length_samples_, fp),
            loop_length_samples_);
  fclose(fp);

  // The audio will be used in a looped manner. To ease the acquisition of an
  // audio frame that crosses the end of the excerpt, we add an extra block
  // length of samples to the end of the array, starting over again from the
  // beginning of the array. Audio frames cross the end of the excerpt always
  // appear as a continuum of memory.
  memcpy(&in_data_[loop_length_samples_], &in_data_[0],
         block_length_sample_ * channels_ * sizeof(int16_t));

  // Maximum number of bytes in output bitstream.
  max_bytes_ = block_length_sample_ * channels_ * sizeof(int16_t);

  out_data_.reset(new int16_t[2 * block_length_sample_ * channels_]);
  bit_stream_.reset(new uint8_t[max_bytes_]);

  // If channels_ == 1, use Opus VOIP mode, otherwise, audio mode.
  int app = channels_ == 1 ? 0 : 1;

  // Create encoder memory.
  EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, channels_, app, 48000));
  EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_, 48000));
  // Set bitrate.
  EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_encoder_, bit_rate_));
}

void OpusFecTest::TearDown() {
  // Free memory.
  EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_));
  EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_));
}

OpusFecTest::OpusFecTest()
    : block_duration_ms_(kOpusBlockDurationMs),
      sampling_khz_(kOpusSamplingKhz),
      block_length_sample_(
          static_cast<size_t>(block_duration_ms_ * sampling_khz_)),
      data_pointer_(0),
      max_bytes_(0),
      encoded_bytes_(0),
      opus_encoder_(NULL),
      opus_decoder_(NULL) {}

void OpusFecTest::EncodeABlock() {
  int value =
      WebRtcOpus_Encode(opus_encoder_, &in_data_[data_pointer_],
                        block_length_sample_, max_bytes_, &bit_stream_[0]);
  EXPECT_GT(value, 0);

  encoded_bytes_ = static_cast<size_t>(value);
}

void OpusFecTest::DecodeABlock(bool lost_previous, bool lost_current) {
  int16_t audio_type;
  int value_1 = 0, value_2 = 0;

  if (lost_previous) {
    // Decode previous frame.
    if (!lost_current &&
        WebRtcOpus_PacketHasFec(&bit_stream_[0], encoded_bytes_) == 1) {
      value_1 =
          WebRtcOpus_DecodeFec(opus_decoder_, &bit_stream_[0], encoded_bytes_,
                               &out_data_[0], &audio_type);
    } else {
      // Call decoder PLC.
      while (value_1 < static_cast<int>(block_length_sample_)) {
        int ret = WebRtcOpus_Decode(opus_decoder_, NULL, 0, &out_data_[value_1],
                                    &audio_type);
        EXPECT_EQ(ret, sampling_khz_ * 10);  // Should return 10 ms of samples.
        value_1 += ret;
      }
    }
    EXPECT_EQ(static_cast<int>(block_length_sample_), value_1);
  }

  if (!lost_current) {
    // Decode current frame.
    value_2 = WebRtcOpus_Decode(opus_decoder_, &bit_stream_[0], encoded_bytes_,
                                &out_data_[value_1 * channels_], &audio_type);
    EXPECT_EQ(static_cast<int>(block_length_sample_), value_2);
  }
}

TEST_P(OpusFecTest, RandomPacketLossTest) {
  const int kDurationMs = 200000;
  int time_now_ms, fec_frames;
  int actual_packet_loss_rate;
  bool lost_current, lost_previous;
  mode mode_set[3] = {{true, 0}, {false, 0}, {true, 50}};

  lost_current = false;
  for (int i = 0; i < 3; i++) {
    if (mode_set[i].fec) {
      EXPECT_EQ(0, WebRtcOpus_EnableFec(opus_encoder_));
      EXPECT_EQ(0, WebRtcOpus_SetPacketLossRate(
                       opus_encoder_, mode_set[i].target_packet_loss_rate));
      printf("FEC is ON, target at packet loss rate %d percent.\n",
             mode_set[i].target_packet_loss_rate);
    } else {
      EXPECT_EQ(0, WebRtcOpus_DisableFec(opus_encoder_));
      printf("FEC is OFF.\n");
    }
    // In this test, we let the target packet loss rate match the actual rate.
    actual_packet_loss_rate = mode_set[i].target_packet_loss_rate;
    // Run every mode a certain time.
    time_now_ms = 0;
    fec_frames = 0;
    while (time_now_ms < kDurationMs) {
      // Encode & decode.
      EncodeABlock();

      // Check if payload has FEC.
      int fec = WebRtcOpus_PacketHasFec(&bit_stream_[0], encoded_bytes_);

      // If FEC is disabled or the target packet loss rate is set to 0, there
      // should be no FEC in the bit stream.
      if (!mode_set[i].fec || mode_set[i].target_packet_loss_rate == 0) {
        EXPECT_EQ(fec, 0);
      } else if (fec == 1) {
        fec_frames++;
      }

      lost_previous = lost_current;
      lost_current = rand() < actual_packet_loss_rate * (RAND_MAX / 100);
      DecodeABlock(lost_previous, lost_current);

      time_now_ms += block_duration_ms_;

      // `data_pointer_` is incremented and wrapped across
      // `loop_length_samples_`.
      data_pointer_ = (data_pointer_ + block_length_sample_ * channels_) %
                      loop_length_samples_;
    }
    if (mode_set[i].fec) {
      printf("%.2f percent frames has FEC.\n",
             static_cast<float>(fec_frames) * block_duration_ms_ / 2000);
    }
  }
}

const coding_param param_set[] = {
    std::make_tuple(1,
                    64000,
                    string("audio_coding/testfile32kHz"),
                    string("pcm")),
    std::make_tuple(1,
                    32000,
                    string("audio_coding/testfile32kHz"),
                    string("pcm")),
    std::make_tuple(2,
                    64000,
                    string("audio_coding/teststereo32kHz"),
                    string("pcm"))};

// 64 kbps, stereo
INSTANTIATE_TEST_SUITE_P(AllTest, OpusFecTest, ::testing::ValuesIn(param_set));

}  // namespace webrtc
