/*
 *  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 <cctype>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>

#include "absl/strings/string_view.h"
#include "api/audio/audio_frame.h"
#include "rtc_base/checks.h"
#include "test/gtest.h"

namespace webrtc {

#define MAX_FILE_NAME_LENGTH_BYTE 500

PCMFile::PCMFile()
    : pcm_file_(nullptr),
      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_(nullptr),
      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) != nullptr);
  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) != nullptr);
  uint16_t tmp_frequency = (uint16_t)atoi(tmp_name);
  if (tmp_frequency > 0) {
    *frequency_hz = tmp_frequency;
  }
  return 0;
}

void PCMFile::Open(absl::string_view file_name,
                   uint16_t frequency,
                   absl::string_view mode,
                   bool auto_rewind) {
  if ((pcm_file_ = fopen(std::string(file_name).c_str(),
                         std::string(mode).c_str())) == nullptr) {
    printf("Cannot open file %s.\n", std::string(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_ = nullptr;
  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
