/*
 *  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/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/engine_configurations.h"
#include "webrtc/modules/media_file/interface/media_file.h"
#include "webrtc/modules/utility/source/file_recorder_impl.h"
#include "webrtc/system_wrappers/include/logging.h"

namespace webrtc {
FileRecorder* FileRecorder::CreateFileRecorder(uint32_t instanceID,
                                               FileFormats fileFormat)
{
    return new FileRecorderImpl(instanceID, fileFormat);
}

void FileRecorder::DestroyFileRecorder(FileRecorder* recorder)
{
    delete recorder;
}

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,
    const TickTime* playoutTS)
{
    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_,
                             (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 webrtc
