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

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

#include "rtc_base/checks.h"
#include "test/gtest.h"

namespace webrtc {

#define MAX_FILE_NAME_LENGTH_BYTE 500

PCMFile::PCMFile()
    : pcm_file_(NULL),
      samples_10ms_(160),
      frequency_(16000),
      end_of_file_(false),
      auto_rewind_(false),
      rewinded_(false),
      read_stereo_(false),
      save_stereo_(false) {
  timestamp_ =
      (((uint32_t)rand() & 0x0000FFFF) << 16) | ((uint32_t)rand() & 0x0000FFFF);
}

PCMFile::PCMFile(uint32_t timestamp)
    : pcm_file_(NULL),
      samples_10ms_(160),
      frequency_(16000),
      end_of_file_(false),
      auto_rewind_(false),
      rewinded_(false),
      read_stereo_(false),
      save_stereo_(false) {
  timestamp_ = timestamp;
}

PCMFile::~PCMFile() {
  if (pcm_file_) {
    fclose(pcm_file_);
  }
}

int16_t PCMFile::ChooseFile(std::string* file_name,
                            int16_t max_len,
                            uint16_t* frequency_hz) {
  char tmp_name[MAX_FILE_NAME_LENGTH_BYTE];

  EXPECT_TRUE(fgets(tmp_name, MAX_FILE_NAME_LENGTH_BYTE, stdin) != NULL);
  tmp_name[MAX_FILE_NAME_LENGTH_BYTE - 1] = '\0';
  int16_t n = 0;

  // Removing trailing spaces.
  while ((isspace(static_cast<unsigned char>(tmp_name[n])) ||
          iscntrl(static_cast<unsigned char>(tmp_name[n]))) &&
         (static_cast<unsigned char>(tmp_name[n]) != 0) &&
         (n < MAX_FILE_NAME_LENGTH_BYTE)) {
    n++;
  }
  if (n > 0) {
    memmove(tmp_name, &tmp_name[n], MAX_FILE_NAME_LENGTH_BYTE - n);
  }

  // Removing trailing spaces.
  n = (int16_t)(strlen(tmp_name) - 1);
  if (n >= 0) {
    while ((isspace(static_cast<unsigned char>(tmp_name[n])) ||
            iscntrl(static_cast<unsigned char>(tmp_name[n]))) &&
           (n >= 0)) {
      n--;
    }
  }
  if (n >= 0) {
    tmp_name[n + 1] = '\0';
  }

  int16_t len = (int16_t)strlen(tmp_name);
  if (len > max_len) {
    return -1;
  }
  if (len > 0) {
    std::string tmp_string(tmp_name, len + 1);
    *file_name = tmp_string;
  }
  printf("Enter the sampling frequency (in Hz) of the above file [%u]: ",
         *frequency_hz);
  EXPECT_TRUE(fgets(tmp_name, 10, stdin) != NULL);
  uint16_t tmp_frequency = (uint16_t)atoi(tmp_name);
  if (tmp_frequency > 0) {
    *frequency_hz = tmp_frequency;
  }
  return 0;
}

void PCMFile::Open(const std::string& file_name,
                   uint16_t frequency,
                   const char* mode,
                   bool auto_rewind) {
  if ((pcm_file_ = fopen(file_name.c_str(), mode)) == NULL) {
    printf("Cannot open file %s.\n", file_name.c_str());
    ADD_FAILURE() << "Unable to read file";
  }
  frequency_ = frequency;
  samples_10ms_ = (uint16_t)(frequency_ / 100);
  auto_rewind_ = auto_rewind;
  end_of_file_ = false;
  rewinded_ = false;
}

int32_t PCMFile::SamplingFrequency() const {
  return frequency_;
}

uint16_t PCMFile::PayloadLength10Ms() const {
  return samples_10ms_;
}

int32_t PCMFile::Read10MsData(AudioFrame& audio_frame) {
  uint16_t channels = 1;
  if (read_stereo_) {
    channels = 2;
  }

  int32_t payload_size =
      (int32_t)fread(audio_frame.mutable_data(), sizeof(uint16_t),
                     samples_10ms_ * channels, pcm_file_);
  if (payload_size < samples_10ms_ * channels) {
    int16_t* frame_data = audio_frame.mutable_data();
    for (int k = payload_size; k < samples_10ms_ * channels; k++) {
      frame_data[k] = 0;
    }
    if (auto_rewind_) {
      rewind(pcm_file_);
      rewinded_ = true;
    } else {
      end_of_file_ = true;
    }
  }
  audio_frame.samples_per_channel_ = samples_10ms_;
  audio_frame.sample_rate_hz_ = frequency_;
  audio_frame.num_channels_ = channels;
  audio_frame.timestamp_ = timestamp_;
  timestamp_ += samples_10ms_;
  ++blocks_read_;
  if (num_10ms_blocks_to_read_ && blocks_read_ >= *num_10ms_blocks_to_read_)
    end_of_file_ = true;
  return samples_10ms_;
}

void PCMFile::Write10MsData(const AudioFrame& audio_frame) {
  if (audio_frame.num_channels_ == 1) {
    if (!save_stereo_) {
      if (fwrite(audio_frame.data(), sizeof(uint16_t),
                 audio_frame.samples_per_channel_, pcm_file_) !=
          static_cast<size_t>(audio_frame.samples_per_channel_)) {
        return;
      }
    } else {
      const int16_t* frame_data = audio_frame.data();
      int16_t* stereo_audio = new int16_t[2 * audio_frame.samples_per_channel_];
      for (size_t k = 0; k < audio_frame.samples_per_channel_; k++) {
        stereo_audio[k << 1] = frame_data[k];
        stereo_audio[(k << 1) + 1] = frame_data[k];
      }
      if (fwrite(stereo_audio, sizeof(int16_t),
                 2 * audio_frame.samples_per_channel_, pcm_file_) !=
          static_cast<size_t>(2 * audio_frame.samples_per_channel_)) {
        return;
      }
      delete[] stereo_audio;
    }
  } else {
    if (fwrite(audio_frame.data(), sizeof(int16_t),
               audio_frame.num_channels_ * audio_frame.samples_per_channel_,
               pcm_file_) !=
        static_cast<size_t>(audio_frame.num_channels_ *
                            audio_frame.samples_per_channel_)) {
      return;
    }
  }
}

void PCMFile::Write10MsData(const int16_t* playout_buffer,
                            size_t length_smpls) {
  if (fwrite(playout_buffer, sizeof(uint16_t), length_smpls, pcm_file_) !=
      length_smpls) {
    return;
  }
}

void PCMFile::Close() {
  fclose(pcm_file_);
  pcm_file_ = NULL;
  blocks_read_ = 0;
}

void PCMFile::FastForward(int num_10ms_blocks) {
  const int channels = read_stereo_ ? 2 : 1;
  long num_bytes_to_move =
      num_10ms_blocks * sizeof(int16_t) * samples_10ms_ * channels;
  int error = fseek(pcm_file_, num_bytes_to_move, SEEK_CUR);
  RTC_DCHECK_EQ(error, 0);
}

void PCMFile::Rewind() {
  rewind(pcm_file_);
  end_of_file_ = false;
  blocks_read_ = 0;
}

bool PCMFile::Rewinded() {
  return rewinded_;
}

void PCMFile::SaveStereo(bool is_stereo) {
  save_stereo_ = is_stereo;
}

void PCMFile::ReadStereo(bool is_stereo) {
  read_stereo_ = is_stereo;
}

void PCMFile::SetNum10MsBlocksToRead(int value) {
  num_10ms_blocks_to_read_ = value;
}

}  // namespace webrtc
