/*
 *  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/iSACTest.h"

#include <stdio.h>
#include <string.h>

#include "absl/strings/match.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/isac/audio_encoder_isac_float.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/time_utils.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {

using ::testing::AnyOf;
using ::testing::Eq;
using ::testing::StrCaseEq;

namespace {

constexpr int kISAC16kPayloadType = 103;
constexpr int kISAC32kPayloadType = 104;
const SdpAudioFormat kISAC16kFormat = {"ISAC", 16000, 1};
const SdpAudioFormat kISAC32kFormat = {"ISAC", 32000, 1};

AudioEncoderIsacFloat::Config TweakConfig(
    AudioEncoderIsacFloat::Config config,
    const ACMTestISACConfig& test_config) {
  if (test_config.currentRateBitPerSec > 0) {
    config.bit_rate = test_config.currentRateBitPerSec;
  }
  if (test_config.currentFrameSizeMsec != 0) {
    config.frame_size_ms = test_config.currentFrameSizeMsec;
  }
  EXPECT_THAT(config.IsOk(), Eq(true));
  return config;
}

void SetISACConfigDefault(ACMTestISACConfig& isacConfig) {
  isacConfig.currentRateBitPerSec = 0;
  isacConfig.currentFrameSizeMsec = 0;
  isacConfig.encodingMode = -1;
  isacConfig.initRateBitPerSec = 0;
  isacConfig.initFrameSizeInMsec = 0;
  isacConfig.enforceFrameSize = false;
}

}  // namespace

ISACTest::ACMTestTimer::ACMTestTimer() : _msec(0), _sec(0), _min(0), _hour(0) {
  return;
}

ISACTest::ACMTestTimer::~ACMTestTimer() {
  return;
}

void ISACTest::ACMTestTimer::Reset() {
  _msec = 0;
  _sec = 0;
  _min = 0;
  _hour = 0;
  return;
}
void ISACTest::ACMTestTimer::Tick10ms() {
  _msec += 10;
  Adjust();
  return;
}

void ISACTest::ACMTestTimer::Tick1ms() {
  _msec++;
  Adjust();
  return;
}

void ISACTest::ACMTestTimer::Tick100ms() {
  _msec += 100;
  Adjust();
  return;
}

void ISACTest::ACMTestTimer::Tick1sec() {
  _sec++;
  Adjust();
  return;
}

void ISACTest::ACMTestTimer::CurrentTimeHMS(char* currTime) {
  sprintf(currTime, "%4lu:%02u:%06.3f", _hour, _min,
          (double)_sec + (double)_msec / 1000.);
  return;
}

void ISACTest::ACMTestTimer::CurrentTime(unsigned long& h,
                                         unsigned char& m,
                                         unsigned char& s,
                                         unsigned short& ms) {
  h = _hour;
  m = _min;
  s = _sec;
  ms = _msec;
  return;
}

void ISACTest::ACMTestTimer::Adjust() {
  unsigned int n;
  if (_msec >= 1000) {
    n = _msec / 1000;
    _msec -= (1000 * n);
    _sec += n;
  }
  if (_sec >= 60) {
    n = _sec / 60;
    _sec -= (n * 60);
    _min += n;
  }
  if (_min >= 60) {
    n = _min / 60;
    _min -= (n * 60);
    _hour += n;
  }
}

ISACTest::ISACTest()
    : _acmA(AudioCodingModule::Create(
          AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))),
      _acmB(AudioCodingModule::Create(
          AudioCodingModule::Config(CreateBuiltinAudioDecoderFactory()))) {}

ISACTest::~ISACTest() {}

void ISACTest::Setup() {
  // Register both iSAC-wb & iSAC-swb in both sides as receiver codecs.
  std::map<int, SdpAudioFormat> receive_codecs = {
      {kISAC16kPayloadType, kISAC16kFormat},
      {kISAC32kPayloadType, kISAC32kFormat}};
  _acmA->SetReceiveCodecs(receive_codecs);
  _acmB->SetReceiveCodecs(receive_codecs);

  //--- Set A-to-B channel
  _channel_A2B.reset(new Channel);
  EXPECT_EQ(0, _acmA->RegisterTransportCallback(_channel_A2B.get()));
  _channel_A2B->RegisterReceiverACM(_acmB.get());

  //--- Set B-to-A channel
  _channel_B2A.reset(new Channel);
  EXPECT_EQ(0, _acmB->RegisterTransportCallback(_channel_B2A.get()));
  _channel_B2A->RegisterReceiverACM(_acmA.get());

  file_name_swb_ =
      webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");

  _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
      *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
      kISAC16kPayloadType));
  _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
      *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
      kISAC32kPayloadType));

  _inFileA.Open(file_name_swb_, 32000, "rb");
  // Set test length to 500 ms (50 blocks of 10 ms each).
  _inFileA.SetNum10MsBlocksToRead(50);
  // Fast-forward 1 second (100 blocks) since the files start with silence.
  _inFileA.FastForward(100);
  std::string fileNameA = webrtc::test::OutputPath() + "testisac_a.pcm";
  std::string fileNameB = webrtc::test::OutputPath() + "testisac_b.pcm";
  _outFileA.Open(fileNameA, 32000, "wb");
  _outFileB.Open(fileNameB, 32000, "wb");

  while (!_inFileA.EndOfFile()) {
    Run10ms();
  }

  _inFileA.Close();
  _outFileA.Close();
  _outFileB.Close();
}

void ISACTest::Perform() {
  Setup();

  int16_t testNr = 0;
  ACMTestISACConfig wbISACConfig;
  ACMTestISACConfig swbISACConfig;

  SetISACConfigDefault(wbISACConfig);
  SetISACConfigDefault(swbISACConfig);

  wbISACConfig.currentRateBitPerSec = -1;
  swbISACConfig.currentRateBitPerSec = -1;
  testNr++;
  EncodeDecode(testNr, wbISACConfig, swbISACConfig);

  SetISACConfigDefault(wbISACConfig);
  SetISACConfigDefault(swbISACConfig);
  testNr++;
  EncodeDecode(testNr, wbISACConfig, swbISACConfig);

  testNr++;
  SwitchingSamplingRate(testNr, 4);
}

void ISACTest::Run10ms() {
  AudioFrame audioFrame;
  EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
  EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
  EXPECT_GE(_acmB->Add10MsData(audioFrame), 0);
  bool muted;
  EXPECT_EQ(0, _acmA->PlayoutData10Ms(32000, &audioFrame, &muted));
  ASSERT_FALSE(muted);
  _outFileA.Write10MsData(audioFrame);
  EXPECT_EQ(0, _acmB->PlayoutData10Ms(32000, &audioFrame, &muted));
  ASSERT_FALSE(muted);
  _outFileB.Write10MsData(audioFrame);
}

void ISACTest::EncodeDecode(int testNr,
                            ACMTestISACConfig& wbISACConfig,
                            ACMTestISACConfig& swbISACConfig) {
  // Files in Side A and B
  _inFileA.Open(file_name_swb_, 32000, "rb", true);
  _inFileB.Open(file_name_swb_, 32000, "rb", true);

  std::string file_name_out;
  rtc::StringBuilder file_stream_a;
  rtc::StringBuilder file_stream_b;
  file_stream_a << webrtc::test::OutputPath();
  file_stream_b << webrtc::test::OutputPath();
  file_stream_a << "out_iSACTest_A_" << testNr << ".pcm";
  file_stream_b << "out_iSACTest_B_" << testNr << ".pcm";
  file_name_out = file_stream_a.str();
  _outFileA.Open(file_name_out, 32000, "wb");
  file_name_out = file_stream_b.str();
  _outFileB.Open(file_name_out, 32000, "wb");

  // Side A is sending super-wideband, and side B is sending wideband.
  _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
      TweakConfig(*AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
                  swbISACConfig),
      kISAC32kPayloadType));
  _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
      TweakConfig(*AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
                  wbISACConfig),
      kISAC16kPayloadType));

  _myTimer.Reset();
  _channel_A2B->ResetStats();
  _channel_B2A->ResetStats();

  char currentTime[500];
  while (!(_inFileA.EndOfFile() || _inFileA.Rewinded())) {
    Run10ms();
    _myTimer.Tick10ms();
    _myTimer.CurrentTimeHMS(currentTime);
  }

  _channel_A2B->ResetStats();
  _channel_B2A->ResetStats();

  _outFileA.Close();
  _outFileB.Close();
  _inFileA.Close();
  _inFileB.Close();
}

void ISACTest::SwitchingSamplingRate(int testNr, int maxSampRateChange) {
  // Files in Side A
  _inFileA.Open(file_name_swb_, 32000, "rb");
  _inFileB.Open(file_name_swb_, 32000, "rb");

  std::string file_name_out;
  rtc::StringBuilder file_stream_a;
  rtc::StringBuilder file_stream_b;
  file_stream_a << webrtc::test::OutputPath();
  file_stream_b << webrtc::test::OutputPath();
  file_stream_a << "out_iSACTest_A_" << testNr << ".pcm";
  file_stream_b << "out_iSACTest_B_" << testNr << ".pcm";
  file_name_out = file_stream_a.str();
  _outFileA.Open(file_name_out, 32000, "wb");
  file_name_out = file_stream_b.str();
  _outFileB.Open(file_name_out, 32000, "wb");

  // Start with side A sending super-wideband and side B seding wideband.
  // Toggle sending wideband/super-wideband in this test.
  _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
      *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
      kISAC32kPayloadType));
  _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
      *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
      kISAC16kPayloadType));

  int numSendCodecChanged = 0;
  _myTimer.Reset();
  char currentTime[50];
  while (numSendCodecChanged < (maxSampRateChange << 1)) {
    Run10ms();
    _myTimer.Tick10ms();
    _myTimer.CurrentTimeHMS(currentTime);
    if (_inFileA.EndOfFile()) {
      if (_inFileA.SamplingFrequency() == 16000) {
        // Switch side A to send super-wideband.
        _inFileA.Close();
        _inFileA.Open(file_name_swb_, 32000, "rb");
        _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
            *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
            kISAC32kPayloadType));
      } else {
        // Switch side A to send wideband.
        _inFileA.Close();
        _inFileA.Open(file_name_swb_, 32000, "rb");
        _acmA->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
            *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
            kISAC16kPayloadType));
      }
      numSendCodecChanged++;
    }

    if (_inFileB.EndOfFile()) {
      if (_inFileB.SamplingFrequency() == 16000) {
        // Switch side B to send super-wideband.
        _inFileB.Close();
        _inFileB.Open(file_name_swb_, 32000, "rb");
        _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
            *AudioEncoderIsacFloat::SdpToConfig(kISAC32kFormat),
            kISAC32kPayloadType));
      } else {
        // Switch side B to send wideband.
        _inFileB.Close();
        _inFileB.Open(file_name_swb_, 32000, "rb");
        _acmB->SetEncoder(AudioEncoderIsacFloat::MakeAudioEncoder(
            *AudioEncoderIsacFloat::SdpToConfig(kISAC16kFormat),
            kISAC16kPayloadType));
      }
      numSendCodecChanged++;
    }
  }
  _outFileA.Close();
  _outFileB.Close();
  _inFileA.Close();
  _inFileB.Close();
}

}  // namespace webrtc
