/*
 *  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 <ctype.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 "system_wrappers/include/sleep.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();
  }

  EXPECT_TRUE(_acmA->ReceiveCodec());
  EXPECT_TRUE(_acmB->ReceiveCodec());

  _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));

  bool adaptiveMode = false;
  if ((swbISACConfig.currentRateBitPerSec == -1) ||
      (wbISACConfig.currentRateBitPerSec == -1)) {
    adaptiveMode = true;
  }
  _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
