/*
 *  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/fileutils.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}},
                                                     {102, {"ILBC", 8000, 1}},
                                                     {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
