/*
 *  Copyright (c) 2012 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/test/EncodeDecodeTest.h"

#include <stdio.h>
#include <stdlib.h>

#include <memory>

#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "rtc_base/strings/string_builder.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {

namespace {
// Buffer size for stereo 48 kHz audio.
constexpr size_t kWebRtc10MsPcmAudio = 960;

}  // namespace

TestPacketization::TestPacketization(RTPStream* rtpStream, uint16_t frequency)
    : _rtpStream(rtpStream), _frequency(frequency), _seqNo(0) {}

TestPacketization::~TestPacketization() {}

int32_t TestPacketization::SendData(const AudioFrameType /* frameType */,
                                    const uint8_t payloadType,
                                    const uint32_t timeStamp,
                                    const uint8_t* payloadData,
                                    const size_t payloadSize,
                                    int64_t absolute_capture_timestamp_ms) {
  _rtpStream->Write(payloadType, timeStamp, _seqNo++, payloadData, payloadSize,
                    _frequency);
  return 1;
}

Sender::Sender()
    : _acm(NULL), _pcmFile(), _audioFrame(), _packetization(NULL) {}

void Sender::Setup(AudioCodingModule* acm,
                   RTPStream* rtpStream,
                   std::string in_file_name,
                   int in_sample_rate,
                   int payload_type,
                   SdpAudioFormat format) {
  // Open input file
  const std::string file_name = webrtc::test::ResourcePath(in_file_name, "pcm");
  _pcmFile.Open(file_name, in_sample_rate, "rb");
  if (format.num_channels == 2) {
    _pcmFile.ReadStereo(true);
  }
  // Set test length to 500 ms (50 blocks of 10 ms each).
  _pcmFile.SetNum10MsBlocksToRead(50);
  // Fast-forward 1 second (100 blocks) since the file starts with silence.
  _pcmFile.FastForward(100);

  acm->SetEncoder(CreateBuiltinAudioEncoderFactory()->MakeAudioEncoder(
      payload_type, format, absl::nullopt));
  _packetization = new TestPacketization(rtpStream, format.clockrate_hz);
  EXPECT_EQ(0, acm->RegisterTransportCallback(_packetization));

  _acm = acm;
}

void Sender::Teardown() {
  _pcmFile.Close();
  delete _packetization;
}

bool Sender::Add10MsData() {
  if (!_pcmFile.EndOfFile()) {
    EXPECT_GT(_pcmFile.Read10MsData(_audioFrame), 0);
    int32_t ok = _acm->Add10MsData(_audioFrame);
    EXPECT_GE(ok, 0);
    return ok >= 0 ? true : false;
  }
  return false;
}

void Sender::Run() {
  while (true) {
    if (!Add10MsData()) {
      break;
    }
  }
}

Receiver::Receiver()
    : _playoutLengthSmpls(kWebRtc10MsPcmAudio),
      _payloadSizeBytes(MAX_INCOMING_PAYLOAD) {}

void Receiver::Setup(AudioCodingModule* acm,
                     RTPStream* rtpStream,
                     std::string out_file_name,
                     size_t channels,
                     int file_num) {
  EXPECT_EQ(0, acm->InitializeReceiver());

  if (channels == 1) {
    acm->SetReceiveCodecs({{103, {"ISAC", 16000, 1}},
                           {104, {"ISAC", 32000, 1}},
                           {107, {"L16", 8000, 1}},
                           {108, {"L16", 16000, 1}},
                           {109, {"L16", 32000, 1}},
                           {0, {"PCMU", 8000, 1}},
                           {8, {"PCMA", 8000, 1}},
                           {102, {"ILBC", 8000, 1}},
                           {9, {"G722", 8000, 1}},
                           {120, {"OPUS", 48000, 2}},
                           {13, {"CN", 8000, 1}},
                           {98, {"CN", 16000, 1}},
                           {99, {"CN", 32000, 1}}});
  } else {
    ASSERT_EQ(channels, 2u);
    acm->SetReceiveCodecs({{111, {"L16", 8000, 2}},
                           {112, {"L16", 16000, 2}},
                           {113, {"L16", 32000, 2}},
                           {110, {"PCMU", 8000, 2}},
                           {118, {"PCMA", 8000, 2}},
                           {119, {"G722", 8000, 2}},
                           {120, {"OPUS", 48000, 2, {{"stereo", "1"}}}}});
  }

  int playSampFreq;
  std::string file_name;
  rtc::StringBuilder file_stream;
  file_stream << webrtc::test::OutputPath() << out_file_name << file_num
              << ".pcm";
  file_name = file_stream.str();
  _rtpStream = rtpStream;

  playSampFreq = 32000;
  _pcmFile.Open(file_name, 32000, "wb+");

  _realPayloadSizeBytes = 0;
  _playoutBuffer = new int16_t[kWebRtc10MsPcmAudio];
  _frequency = playSampFreq;
  _acm = acm;
  _firstTime = true;
}

void Receiver::Teardown() {
  delete[] _playoutBuffer;
  _pcmFile.Close();
}

bool Receiver::IncomingPacket() {
  if (!_rtpStream->EndOfFile()) {
    if (_firstTime) {
      _firstTime = false;
      _realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
                                               _payloadSizeBytes, &_nextTime);
      if (_realPayloadSizeBytes == 0) {
        if (_rtpStream->EndOfFile()) {
          _firstTime = true;
          return true;
        } else {
          return false;
        }
      }
    }

    EXPECT_EQ(0, _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes,
                                      _rtpHeader));
    _realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
                                             _payloadSizeBytes, &_nextTime);
    if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) {
      _firstTime = true;
    }
  }
  return true;
}

bool Receiver::PlayoutData() {
  AudioFrame audioFrame;
  bool muted;
  int32_t ok = _acm->PlayoutData10Ms(_frequency, &audioFrame, &muted);
  if (muted) {
    ADD_FAILURE();
    return false;
  }
  EXPECT_EQ(0, ok);
  if (ok < 0) {
    return false;
  }
  if (_playoutLengthSmpls == 0) {
    return false;
  }
  _pcmFile.Write10MsData(audioFrame.data(), audioFrame.samples_per_channel_ *
                                                audioFrame.num_channels_);
  return true;
}

void Receiver::Run() {
  uint8_t counter500Ms = 50;
  uint32_t clock = 0;

  while (counter500Ms > 0) {
    if (clock == 0 || clock >= _nextTime) {
      EXPECT_TRUE(IncomingPacket());
      if (clock == 0) {
        clock = _nextTime;
      }
    }
    if ((clock % 10) == 0) {
      if (!PlayoutData()) {
        clock++;
        continue;
      }
    }
    if (_rtpStream->EndOfFile()) {
      counter500Ms--;
    }
    clock++;
  }
}

EncodeDecodeTest::EncodeDecodeTest() = default;

void EncodeDecodeTest::Perform() {
  const std::map<int, SdpAudioFormat> send_codecs = {
      {103, {"ISAC", 16000, 1}}, {104, {"ISAC", 32000, 1}},
      {107, {"L16", 8000, 1}},   {108, {"L16", 16000, 1}},
      {109, {"L16", 32000, 1}},  {0, {"PCMU", 8000, 1}},
      {8, {"PCMA", 8000, 1}},
#ifdef WEBRTC_CODEC_ILBC
      {102, {"ILBC", 8000, 1}},
#endif
      {9, {"G722", 8000, 1}}};
  int file_num = 0;
  for (const auto& send_codec : send_codecs) {
    RTPFile rtpFile;
    std::unique_ptr<AudioCodingModule> acm(AudioCodingModule::Create(
        AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory())));

    std::string fileName = webrtc::test::TempFilename(
        webrtc::test::OutputPath(), "encode_decode_rtp");
    rtpFile.Open(fileName.c_str(), "wb+");
    rtpFile.WriteHeader();
    Sender sender;
    sender.Setup(acm.get(), &rtpFile, "audio_coding/testfile32kHz", 32000,
                 send_codec.first, send_codec.second);
    sender.Run();
    sender.Teardown();
    rtpFile.Close();

    rtpFile.Open(fileName.c_str(), "rb");
    rtpFile.ReadHeader();
    Receiver receiver;
    receiver.Setup(acm.get(), &rtpFile, "encodeDecode_out", 1, file_num);
    receiver.Run();
    receiver.Teardown();
    rtpFile.Close();

    file_num++;
  }
}

}  // namespace webrtc
