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

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

TestPacketization::~TestPacketization() {
}

int32_t TestPacketization::SendData(
    const FrameType /* frameType */, const uint8_t payloadType,
    const uint32_t timeStamp, const uint8_t* payloadData,
    const size_t payloadSize,
    const RTPFragmentationHeader* /* fragmentation */) {
  _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(WEBRTC_10MS_PCM_AUDIO),
      _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[WEBRTC_10MS_PCM_AUDIO];
  _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(&_rtpInfo, _incomingPayload,
                                               _payloadSizeBytes, &_nextTime);
      if (_realPayloadSizeBytes == 0) {
        if (_rtpStream->EndOfFile()) {
          _firstTime = true;
          return true;
        } else {
          return false;
        }
      }
    }

    EXPECT_EQ(0, _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes,
                                      _rtpInfo));
    _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _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
