/*
 *  Copyright (c) 2011 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 "utility.h"

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

#include "common_types.h"  // NOLINT(build/include)
#include "modules/audio_coding/include/audio_coding_module.h"
#include "test/gtest.h"

#define NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE 13

namespace webrtc {

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

ACMTestTimer::~ACMTestTimer() {
  return;
}

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

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

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

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

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

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

void 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;
  }
}

int16_t ChooseCodec(CodecInst& codecInst) {
  PrintCodecs();
  // AudioCodingModule* tmpACM = AudioCodingModule::Create(0);
  uint8_t noCodec = AudioCodingModule::NumberOfCodecs();
  int8_t codecID;
  bool outOfRange = false;
  char myStr[15] = "";
  do {
    printf("\nChoose a codec [0]: ");
    EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL);
    codecID = atoi(myStr);
    if ((codecID < 0) || (codecID >= noCodec)) {
      printf("\nOut of range.\n");
      outOfRange = true;
    }
  } while (outOfRange);

  CHECK_ERROR(AudioCodingModule::Codec((uint8_t)codecID, &codecInst));
  return 0;
}

void PrintCodecs() {
  uint8_t noCodec = AudioCodingModule::NumberOfCodecs();

  CodecInst codecInst;
  printf("No  Name                [Hz]    [bps]\n");
  for (uint8_t codecCntr = 0; codecCntr < noCodec; codecCntr++) {
    AudioCodingModule::Codec(codecCntr, &codecInst);
    printf("%2d- %-18s %5d   %6d\n", codecCntr, codecInst.plname,
           codecInst.plfreq, codecInst.rate);
  }
}

namespace test {

CircularBuffer::CircularBuffer(uint32_t len)
    : _buff(NULL),
      _idx(0),
      _buffIsFull(false),
      _calcAvg(false),
      _calcVar(false),
      _sum(0),
      _sumSqr(0) {
  _buff = new double[len];
  if (_buff == NULL) {
    _buffLen = 0;
  } else {
    for (uint32_t n = 0; n < len; n++) {
      _buff[n] = 0;
    }
    _buffLen = len;
  }
}

CircularBuffer::~CircularBuffer() {
  if (_buff != NULL) {
    delete[] _buff;
    _buff = NULL;
  }
}

void CircularBuffer::Update(const double newVal) {
  assert(_buffLen > 0);

  // store the value that is going to be overwritten
  double oldVal = _buff[_idx];
  // record the new value
  _buff[_idx] = newVal;
  // increment the index, to point to where we would
  // write next
  _idx++;
  // it is a circular buffer, if we are at the end
  // we have to cycle to the beginning
  if (_idx >= _buffLen) {
    // flag that the buffer is filled up.
    _buffIsFull = true;
    _idx = 0;
  }

  // Update

  if (_calcAvg) {
    // for the average we have to update
    // the sum
    _sum += (newVal - oldVal);
  }

  if (_calcVar) {
    // to calculate variance we have to update
    // the sum of squares
    _sumSqr += (double)(newVal - oldVal) * (double)(newVal + oldVal);
  }
}

void CircularBuffer::SetArithMean(bool enable) {
  assert(_buffLen > 0);

  if (enable && !_calcAvg) {
    uint32_t lim;
    if (_buffIsFull) {
      lim = _buffLen;
    } else {
      lim = _idx;
    }
    _sum = 0;
    for (uint32_t n = 0; n < lim; n++) {
      _sum += _buff[n];
    }
  }
  _calcAvg = enable;
}

void CircularBuffer::SetVariance(bool enable) {
  assert(_buffLen > 0);

  if (enable && !_calcVar) {
    uint32_t lim;
    if (_buffIsFull) {
      lim = _buffLen;
    } else {
      lim = _idx;
    }
    _sumSqr = 0;
    for (uint32_t n = 0; n < lim; n++) {
      _sumSqr += _buff[n] * _buff[n];
    }
  }
  _calcAvg = enable;
}

int16_t CircularBuffer::ArithMean(double& mean) {
  assert(_buffLen > 0);

  if (_buffIsFull) {
    mean = _sum / (double)_buffLen;
    return 0;
  } else {
    if (_idx > 0) {
      mean = _sum / (double)_idx;
      return 0;
    } else {
      return -1;
    }
  }
}

int16_t CircularBuffer::Variance(double& var) {
  assert(_buffLen > 0);

  if (_buffIsFull) {
    var = _sumSqr / (double)_buffLen;
    return 0;
  } else {
    if (_idx > 0) {
      var = _sumSqr / (double)_idx;
      return 0;
    } else {
      return -1;
    }
  }
}

}  // namespace test

bool FixedPayloadTypeCodec(const char* payloadName) {
  char fixPayloadTypeCodecs[NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE][32] = {
      "PCMU", "PCMA",  "GSM", "G723", "DVI4", "LPC", "PCMA",
      "G722", "QCELP", "CN",  "MPA",  "G728", "G729"};

  for (int n = 0; n < NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE; n++) {
    if (!STR_CASE_CMP(payloadName, fixPayloadTypeCodecs[n])) {
      return true;
    }
  }
  return false;
}

void VADCallback::Reset() {
  memset(_numFrameTypes, 0, sizeof(_numFrameTypes));
}

VADCallback::VADCallback() {
  memset(_numFrameTypes, 0, sizeof(_numFrameTypes));
}

void VADCallback::PrintFrameTypes() {
  printf("kEmptyFrame......... %d\n", _numFrameTypes[kEmptyFrame]);
  printf("kAudioFrameSpeech... %d\n", _numFrameTypes[kAudioFrameSpeech]);
  printf("kAudioFrameCN....... %d\n", _numFrameTypes[kAudioFrameCN]);
  printf("kVideoFrameKey...... %d\n", _numFrameTypes[kVideoFrameKey]);
  printf("kVideoFrameDelta.... %d\n", _numFrameTypes[kVideoFrameDelta]);
}

int32_t VADCallback::InFrameType(FrameType frame_type) {
  _numFrameTypes[frame_type]++;
  return 0;
}

}  // namespace webrtc
