/*
 *  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/utility/include/file_recorder.h"

#include <list>

#include "webrtc/base/platform_thread.h"
#include "webrtc/common_audio/resampler/include/resampler.h"
#include "webrtc/common_types.h"
#include "webrtc/engine_configurations.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/media_file/media_file.h"
#include "webrtc/modules/media_file/media_file_defines.h"
#include "webrtc/modules/utility/source/coder.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/system_wrappers/include/logging.h"
#include "webrtc/typedefs.h"

namespace webrtc {

namespace {

// The largest decoded frame size in samples (60ms with 32kHz sample rate).
enum { MAX_AUDIO_BUFFER_IN_SAMPLES = 60 * 32 };
enum { MAX_AUDIO_BUFFER_IN_BYTES = MAX_AUDIO_BUFFER_IN_SAMPLES * 2 };
enum { kMaxAudioBufferQueueLength = 100 };

class CriticalSectionWrapper;

class FileRecorderImpl : public FileRecorder {
 public:
  FileRecorderImpl(uint32_t instanceID, FileFormats fileFormat);
  ~FileRecorderImpl() override;

  // FileRecorder functions.
  int32_t RegisterModuleFileCallback(FileCallback* callback) override;
  FileFormats RecordingFileFormat() const override;
  int32_t StartRecordingAudioFile(const char* fileName,
                                  const CodecInst& codecInst,
                                  uint32_t notificationTimeMs) override;
  int32_t StartRecordingAudioFile(OutStream* destStream,
                                  const CodecInst& codecInst,
                                  uint32_t notificationTimeMs) override;
  int32_t StopRecording() override;
  bool IsRecording() const override;
  int32_t codec_info(CodecInst* codecInst) const override;
  int32_t RecordAudioToFile(const AudioFrame& frame) override;

 private:
  int32_t WriteEncodedAudioData(const int8_t* audioBuffer, size_t bufferLength);

  int32_t SetUpAudioEncoder();

  uint32_t _instanceID;
  FileFormats _fileFormat;
  MediaFile* _moduleFile;

  CodecInst codec_info_;
  int8_t _audioBuffer[MAX_AUDIO_BUFFER_IN_BYTES];
  AudioCoder _audioEncoder;
  Resampler _audioResampler;
};

FileRecorderImpl::FileRecorderImpl(uint32_t instanceID, FileFormats fileFormat)
    : _instanceID(instanceID),
      _fileFormat(fileFormat),
      _moduleFile(MediaFile::CreateMediaFile(_instanceID)),
      codec_info_(),
      _audioBuffer(),
      _audioEncoder(instanceID),
      _audioResampler() {}

FileRecorderImpl::~FileRecorderImpl() {
  MediaFile::DestroyMediaFile(_moduleFile);
}

FileFormats FileRecorderImpl::RecordingFileFormat() const {
  return _fileFormat;
}

int32_t FileRecorderImpl::RegisterModuleFileCallback(FileCallback* callback) {
  if (_moduleFile == NULL) {
    return -1;
  }
  return _moduleFile->SetModuleFileCallback(callback);
}

int32_t FileRecorderImpl::StartRecordingAudioFile(const char* fileName,
                                                  const CodecInst& codecInst,
                                                  uint32_t notificationTimeMs) {
  if (_moduleFile == NULL) {
    return -1;
  }
  codec_info_ = codecInst;
  int32_t retVal = 0;
  retVal = _moduleFile->StartRecordingAudioFile(fileName, _fileFormat,
                                                codecInst, notificationTimeMs);

  if (retVal == 0) {
    retVal = SetUpAudioEncoder();
  }
  if (retVal != 0) {
    LOG(LS_WARNING) << "Failed to initialize file " << fileName
                    << " for recording.";

    if (IsRecording()) {
      StopRecording();
    }
  }
  return retVal;
}

int32_t FileRecorderImpl::StartRecordingAudioFile(OutStream* destStream,
                                                  const CodecInst& codecInst,
                                                  uint32_t notificationTimeMs) {
  codec_info_ = codecInst;
  int32_t retVal = _moduleFile->StartRecordingAudioStream(
      *destStream, _fileFormat, codecInst, notificationTimeMs);

  if (retVal == 0) {
    retVal = SetUpAudioEncoder();
  }
  if (retVal != 0) {
    LOG(LS_WARNING) << "Failed to initialize outStream for recording.";

    if (IsRecording()) {
      StopRecording();
    }
  }
  return retVal;
}

int32_t FileRecorderImpl::StopRecording() {
  memset(&codec_info_, 0, sizeof(CodecInst));
  return _moduleFile->StopRecording();
}

bool FileRecorderImpl::IsRecording() const {
  return _moduleFile->IsRecording();
}

int32_t FileRecorderImpl::RecordAudioToFile(
    const AudioFrame& incomingAudioFrame) {
  if (codec_info_.plfreq == 0) {
    LOG(LS_WARNING) << "RecordAudioToFile() recording audio is not "
                    << "turned on.";
    return -1;
  }
  AudioFrame tempAudioFrame;
  tempAudioFrame.samples_per_channel_ = 0;
  if (incomingAudioFrame.num_channels_ == 2 && !_moduleFile->IsStereo()) {
    // Recording mono but incoming audio is (interleaved) stereo.
    tempAudioFrame.num_channels_ = 1;
    tempAudioFrame.sample_rate_hz_ = incomingAudioFrame.sample_rate_hz_;
    tempAudioFrame.samples_per_channel_ =
        incomingAudioFrame.samples_per_channel_;
    for (size_t i = 0; i < (incomingAudioFrame.samples_per_channel_); i++) {
      // Sample value is the average of left and right buffer rounded to
      // closest integer value. Note samples can be either 1 or 2 byte.
      tempAudioFrame.data_[i] = ((incomingAudioFrame.data_[2 * i] +
                                  incomingAudioFrame.data_[(2 * i) + 1] + 1) >>
                                 1);
    }
  } else if (incomingAudioFrame.num_channels_ == 1 && _moduleFile->IsStereo()) {
    // Recording stereo but incoming audio is mono.
    tempAudioFrame.num_channels_ = 2;
    tempAudioFrame.sample_rate_hz_ = incomingAudioFrame.sample_rate_hz_;
    tempAudioFrame.samples_per_channel_ =
        incomingAudioFrame.samples_per_channel_;
    for (size_t i = 0; i < (incomingAudioFrame.samples_per_channel_); i++) {
      // Duplicate sample to both channels
      tempAudioFrame.data_[2 * i] = incomingAudioFrame.data_[i];
      tempAudioFrame.data_[2 * i + 1] = incomingAudioFrame.data_[i];
    }
  }

  const AudioFrame* ptrAudioFrame = &incomingAudioFrame;
  if (tempAudioFrame.samples_per_channel_ != 0) {
    // If ptrAudioFrame is not empty it contains the audio to be recorded.
    ptrAudioFrame = &tempAudioFrame;
  }

  // Encode the audio data before writing to file. Don't encode if the codec
  // is PCM.
  // NOTE: stereo recording is only supported for WAV files.
  // TODO(hellner): WAV expect PCM in little endian byte order. Not
  // "encoding" with PCM coder should be a problem for big endian systems.
  size_t encodedLenInBytes = 0;
  if (_fileFormat == kFileFormatPreencodedFile ||
      STR_CASE_CMP(codec_info_.plname, "L16") != 0) {
    if (_audioEncoder.Encode(*ptrAudioFrame, _audioBuffer,
                             &encodedLenInBytes) == -1) {
      LOG(LS_WARNING) << "RecordAudioToFile() codec " << codec_info_.plname
                      << " not supported or failed to encode stream.";
      return -1;
    }
  } else {
    size_t outLen = 0;
    _audioResampler.ResetIfNeeded(ptrAudioFrame->sample_rate_hz_,
                                  codec_info_.plfreq,
                                  ptrAudioFrame->num_channels_);
    _audioResampler.Push(
        ptrAudioFrame->data_,
        ptrAudioFrame->samples_per_channel_ * ptrAudioFrame->num_channels_,
        reinterpret_cast<int16_t*>(_audioBuffer), MAX_AUDIO_BUFFER_IN_BYTES,
        outLen);
    encodedLenInBytes = outLen * sizeof(int16_t);
  }

  // Codec may not be operating at a frame rate of 10 ms. Whenever enough
  // 10 ms chunks of data has been pushed to the encoder an encoded frame
  // will be available. Wait until then.
  if (encodedLenInBytes) {
    if (WriteEncodedAudioData(_audioBuffer, encodedLenInBytes) == -1) {
      return -1;
    }
  }
  return 0;
}

int32_t FileRecorderImpl::SetUpAudioEncoder() {
  if (_fileFormat == kFileFormatPreencodedFile ||
      STR_CASE_CMP(codec_info_.plname, "L16") != 0) {
    if (_audioEncoder.SetEncodeCodec(codec_info_) == -1) {
      LOG(LS_ERROR) << "SetUpAudioEncoder() codec " << codec_info_.plname
                    << " not supported.";
      return -1;
    }
  }
  return 0;
}

int32_t FileRecorderImpl::codec_info(CodecInst* codecInst) const {
  if (codec_info_.plfreq == 0) {
    return -1;
  }
  *codecInst = codec_info_;
  return 0;
}

int32_t FileRecorderImpl::WriteEncodedAudioData(const int8_t* audioBuffer,
                                                size_t bufferLength) {
  return _moduleFile->IncomingAudioData(audioBuffer, bufferLength);
}

}  // namespace

std::unique_ptr<FileRecorder> FileRecorder::CreateFileRecorder(
    uint32_t instanceID,
    FileFormats fileFormat) {
  return std::unique_ptr<FileRecorder>(
      new FileRecorderImpl(instanceID, fileFormat));
}

}  // namespace webrtc
