/*
 *  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 "absl/strings/match.h"
#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 (absl::EqualsIgnoreCase(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
