/*
 *  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 "webrtc/modules/audio_coding/main/test/iSACTest.h"

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

#if _WIN32
#include <windows.h>
#elif WEBRTC_LINUX
#include <time.h>
#else
#include <sys/time.h>
#include <time.h>
#endif

#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
#include "webrtc/modules/audio_coding/main/test/utility.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/tick_util.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/test/testsupport/fileutils.h"

namespace webrtc {

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

int16_t SetISAConfig(ACMTestISACConfig& isacConfig, AudioCodingModule* acm,
                     int testMode) {

  if ((isacConfig.currentRateBitPerSec != 0)
      || (isacConfig.currentFrameSizeMsec != 0)) {
    CodecInst sendCodec;
    EXPECT_EQ(0, acm->SendCodec(&sendCodec));
    if (isacConfig.currentRateBitPerSec < 0) {
      // Register iSAC in adaptive (channel-dependent) mode.
      sendCodec.rate = -1;
      EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec));
    } else {
      if (isacConfig.currentRateBitPerSec != 0) {
        sendCodec.rate = isacConfig.currentRateBitPerSec;
      }
      if (isacConfig.currentFrameSizeMsec != 0) {
        sendCodec.pacsize = isacConfig.currentFrameSizeMsec
            * (sendCodec.plfreq / 1000);
      }
      EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec));
    }
  }

  if (isacConfig.maxRateBitPerSec > 0) {
    // Set max rate.
    EXPECT_EQ(0, acm->SetISACMaxRate(isacConfig.maxRateBitPerSec));
  }
  if (isacConfig.maxPayloadSizeByte > 0) {
    // Set max payload size.
    EXPECT_EQ(0, acm->SetISACMaxPayloadSize(isacConfig.maxPayloadSizeByte));
  }
  if ((isacConfig.initFrameSizeInMsec != 0)
      || (isacConfig.initRateBitPerSec != 0)) {
    EXPECT_EQ(0, acm->ConfigISACBandwidthEstimator(
        static_cast<uint8_t>(isacConfig.initFrameSizeInMsec),
        static_cast<uint16_t>(isacConfig.initRateBitPerSec),
        isacConfig.enforceFrameSize));
  }

  return 0;
}

ISACTest::ISACTest(int testMode)
    : _acmA(AudioCodingModule::Create(1)),
      _acmB(AudioCodingModule::Create(2)),
      _testMode(testMode) {}

ISACTest::~ISACTest() {}

void ISACTest::Setup() {
  int codecCntr;
  CodecInst codecParam;

  for (codecCntr = 0; codecCntr < AudioCodingModule::NumberOfCodecs();
      codecCntr++) {
    EXPECT_EQ(0, AudioCodingModule::Codec(codecCntr, &codecParam));
    if (!STR_CASE_CMP(codecParam.plname, "ISAC")
        && codecParam.plfreq == 16000) {
      memcpy(&_paramISAC16kHz, &codecParam, sizeof(CodecInst));
      _idISAC16kHz = codecCntr;
    }
    if (!STR_CASE_CMP(codecParam.plname, "ISAC")
        && codecParam.plfreq == 32000) {
      memcpy(&_paramISAC32kHz, &codecParam, sizeof(CodecInst));
      _idISAC32kHz = codecCntr;
    }
  }

  // Register both iSAC-wb & iSAC-swb in both sides as receiver codecs.
  EXPECT_EQ(0, _acmA->RegisterReceiveCodec(_paramISAC16kHz));
  EXPECT_EQ(0, _acmA->RegisterReceiveCodec(_paramISAC32kHz));
  EXPECT_EQ(0, _acmB->RegisterReceiveCodec(_paramISAC16kHz));
  EXPECT_EQ(0, _acmB->RegisterReceiveCodec(_paramISAC32kHz));

  //--- 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");

  EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
  EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));

  _inFileA.Open(file_name_swb_, 32000, "rb");
  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();
  }
  CodecInst receiveCodec;
  EXPECT_EQ(0, _acmA->ReceiveCodec(&receiveCodec));
  EXPECT_EQ(0, _acmB->ReceiveCodec(&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);

  if (_testMode != 0) {
    SetISACConfigDefault(wbISACConfig);
    SetISACConfigDefault(swbISACConfig);

    wbISACConfig.currentRateBitPerSec = -1;
    swbISACConfig.currentRateBitPerSec = -1;
    wbISACConfig.initRateBitPerSec = 13000;
    wbISACConfig.initFrameSizeInMsec = 60;
    swbISACConfig.initRateBitPerSec = 20000;
    swbISACConfig.initFrameSizeInMsec = 30;
    testNr++;
    EncodeDecode(testNr, wbISACConfig, swbISACConfig);

    SetISACConfigDefault(wbISACConfig);
    SetISACConfigDefault(swbISACConfig);

    wbISACConfig.currentRateBitPerSec = 20000;
    swbISACConfig.currentRateBitPerSec = 48000;
    testNr++;
    EncodeDecode(testNr, wbISACConfig, swbISACConfig);

    wbISACConfig.currentRateBitPerSec = 16000;
    swbISACConfig.currentRateBitPerSec = 30000;
    wbISACConfig.currentFrameSizeMsec = 60;
    testNr++;
    EncodeDecode(testNr, wbISACConfig, swbISACConfig);
  }

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

  int user_input;
  if ((_testMode == 0) || (_testMode == 1)) {
    swbISACConfig.maxPayloadSizeByte = static_cast<uint16_t>(200);
    wbISACConfig.maxPayloadSizeByte = static_cast<uint16_t>(200);
  } else {
    printf("Enter the max payload-size for side A: ");
    CHECK_ERROR(scanf("%d", &user_input));
    swbISACConfig.maxPayloadSizeByte = (uint16_t) user_input;
    printf("Enter the max payload-size for side B: ");
    CHECK_ERROR(scanf("%d", &user_input));
    wbISACConfig.maxPayloadSizeByte = (uint16_t) user_input;
  }
  testNr++;
  EncodeDecode(testNr, wbISACConfig, swbISACConfig);

  _acmA->ResetEncoder();
  _acmB->ResetEncoder();
  SetISACConfigDefault(wbISACConfig);
  SetISACConfigDefault(swbISACConfig);

  if ((_testMode == 0) || (_testMode == 1)) {
    swbISACConfig.maxRateBitPerSec = static_cast<uint32_t>(48000);
    wbISACConfig.maxRateBitPerSec = static_cast<uint32_t>(48000);
  } else {
    printf("Enter the max rate for side A: ");
    CHECK_ERROR(scanf("%d", &user_input));
    swbISACConfig.maxRateBitPerSec = (uint32_t) user_input;
    printf("Enter the max rate for side B: ");
    CHECK_ERROR(scanf("%d", &user_input));
    wbISACConfig.maxRateBitPerSec = (uint32_t) user_input;
  }

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

  testNr++;
  if (_testMode == 0) {
    SwitchingSamplingRate(testNr, 4);
  } else {
    SwitchingSamplingRate(testNr, 80);
  }
}

void ISACTest::Run10ms() {
  AudioFrame audioFrame;
  EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0);
  EXPECT_GE(_acmA->Add10MsData(audioFrame), 0);
  EXPECT_GE(_acmB->Add10MsData(audioFrame), 0);
  EXPECT_EQ(0, _acmA->PlayoutData10Ms(32000, &audioFrame));
  _outFileA.Write10MsData(audioFrame);
  EXPECT_EQ(0, _acmB->PlayoutData10Ms(32000, &audioFrame));
  _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;
  std::stringstream file_stream_a;
  std::stringstream 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");

  EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC16kHz));
  EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
  EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC32kHz));
  EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));

  // Side A is sending super-wideband, and side B is sending wideband.
  SetISAConfig(swbISACConfig, _acmA.get(), _testMode);
  SetISAConfig(wbISACConfig, _acmB.get(), _testMode);

  bool adaptiveMode = false;
  if ((swbISACConfig.currentRateBitPerSec == -1)
      || (wbISACConfig.currentRateBitPerSec == -1)) {
    adaptiveMode = true;
  }
  _myTimer.Reset();
  _channel_A2B->ResetStats();
  _channel_B2A->ResetStats();

  char currentTime[500];
  CodecInst sendCodec;
  EventWrapper* myEvent = EventWrapper::Create();
  EXPECT_TRUE(myEvent->StartTimer(true, 10));
  while (!(_inFileA.EndOfFile() || _inFileA.Rewinded())) {
    Run10ms();
    _myTimer.Tick10ms();
    _myTimer.CurrentTimeHMS(currentTime);

    if ((adaptiveMode) && (_testMode != 0)) {
      myEvent->Wait(5000);
      EXPECT_EQ(0, _acmA->SendCodec(&sendCodec));
      EXPECT_EQ(0, _acmB->SendCodec(&sendCodec));
    }
  }

  if (_testMode != 0) {
    printf("\n\nSide A statistics\n\n");
    _channel_A2B->PrintStats(_paramISAC32kHz);

    printf("\n\nSide B statistics\n\n");
    _channel_B2A->PrintStats(_paramISAC16kHz);
  }

  _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;
  std::stringstream file_stream_a;
  std::stringstream 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.
  EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
  EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));

  int numSendCodecChanged = 0;
  _myTimer.Reset();
  char currentTime[50];
  while (numSendCodecChanged < (maxSampRateChange << 1)) {
    Run10ms();
    _myTimer.Tick10ms();
    _myTimer.CurrentTimeHMS(currentTime);
    if (_testMode == 2)
      printf("\r%s", currentTime);
    if (_inFileA.EndOfFile()) {
      if (_inFileA.SamplingFrequency() == 16000) {
        // Switch side A to send super-wideband.
        _inFileA.Close();
        _inFileA.Open(file_name_swb_, 32000, "rb");
        EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz));
      } else {
        // Switch side A to send wideband.
        _inFileA.Close();
        _inFileA.Open(file_name_swb_, 32000, "rb");
        EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC16kHz));
      }
      numSendCodecChanged++;
    }

    if (_inFileB.EndOfFile()) {
      if (_inFileB.SamplingFrequency() == 16000) {
        // Switch side B to send super-wideband.
        _inFileB.Close();
        _inFileB.Open(file_name_swb_, 32000, "rb");
        EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC32kHz));
      } else {
        // Switch side B to send wideband.
        _inFileB.Close();
        _inFileB.Open(file_name_swb_, 32000, "rb");
        EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz));
      }
      numSendCodecChanged++;
    }
  }
  _outFileA.Close();
  _outFileB.Close();
  _inFileA.Close();
  _inFileB.Close();
}

}  // namespace webrtc
