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

#include "webrtc/modules/media_file/interface/media_file.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/file_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/voice_engine/channel.h"
#include "webrtc/voice_engine/include/voe_errors.h"
#include "webrtc/voice_engine/output_mixer.h"
#include "webrtc/voice_engine/transmit_mixer.h"
#include "webrtc/voice_engine/voice_engine_impl.h"

namespace webrtc {

VoEFile* VoEFile::GetInterface(VoiceEngine* voiceEngine)
{
#ifndef WEBRTC_VOICE_ENGINE_FILE_API
    return NULL;
#else
    if (NULL == voiceEngine)
    {
        return NULL;
    }
    VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
    s->AddRef();
    return s;
#endif
}

#ifdef WEBRTC_VOICE_ENGINE_FILE_API

VoEFileImpl::VoEFileImpl(voe::SharedData* shared) : _shared(shared)
{
    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "VoEFileImpl::VoEFileImpl() - ctor");
}

VoEFileImpl::~VoEFileImpl()
{
    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "VoEFileImpl::~VoEFileImpl() - dtor");
}

int VoEFileImpl::StartPlayingFileLocally(
    int channel,
    const char fileNameUTF8[1024],
    bool loop, FileFormats format,
    float volumeScaling,
    int startPointMs,
    int stopPointMs)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StartPlayingFileLocally(channel=%d, fileNameUTF8[]=%s, "
                 "loop=%d, format=%d, volumeScaling=%5.3f, startPointMs=%d,"
                 " stopPointMs=%d)",
                 channel, fileNameUTF8, loop, format, volumeScaling,
                 startPointMs, stopPointMs);
    assert(1024 == FileWrapper::kMaxFileNameSize);
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
    voe::Channel* channelPtr = ch.channel();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "StartPlayingFileLocally() failed to locate channel");
        return -1;
    }

    return channelPtr->StartPlayingFileLocally(fileNameUTF8,
                                               loop,
                                               format,
                                               startPointMs,
                                               volumeScaling,
                                               stopPointMs,
                                               NULL);
}

int VoEFileImpl::StartPlayingFileLocally(int channel,
                                         InStream* stream,
                                         FileFormats format,
                                         float volumeScaling,
                                         int startPointMs,
                                         int stopPointMs)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StartPlayingFileLocally(channel=%d, stream, format=%d, "
                 "volumeScaling=%5.3f, startPointMs=%d, stopPointMs=%d)",
                 channel, format, volumeScaling, startPointMs, stopPointMs);

    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
    voe::Channel* channelPtr = ch.channel();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "StartPlayingFileLocally() failed to locate channel");
        return -1;
    }

    return channelPtr->StartPlayingFileLocally(stream,
                                               format,
                                               startPointMs,
                                               volumeScaling,
                                               stopPointMs,
                                               NULL);
}

int VoEFileImpl::StopPlayingFileLocally(int channel)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StopPlayingFileLocally()");
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
    voe::Channel* channelPtr = ch.channel();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "StopPlayingFileLocally() failed to locate channel");
        return -1;
    }
    return channelPtr->StopPlayingFileLocally();
}

int VoEFileImpl::IsPlayingFileLocally(int channel)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "IsPlayingFileLocally(channel=%d)", channel);
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
    voe::Channel* channelPtr = ch.channel();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "StopPlayingFileLocally() failed to locate channel");
        return -1;
    }
    return channelPtr->IsPlayingFileLocally();
}

int VoEFileImpl::StartPlayingFileAsMicrophone(int channel,
                                              const char fileNameUTF8[1024],
                                              bool loop,
                                              bool mixWithMicrophone,
                                              FileFormats format,
                                              float volumeScaling)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StartPlayingFileAsMicrophone(channel=%d, fileNameUTF8=%s, "
                 "loop=%d, mixWithMicrophone=%d, format=%d, "
                 "volumeScaling=%5.3f)",
                 channel, fileNameUTF8, loop, mixWithMicrophone, format,
                 volumeScaling);
    assert(1024 == FileWrapper::kMaxFileNameSize);
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    const uint32_t startPointMs(0);
    const uint32_t stopPointMs(0);

    if (channel == -1)
    {
        int res = _shared->transmit_mixer()->StartPlayingFileAsMicrophone(
            fileNameUTF8,
            loop,
            format,
            startPointMs,
            volumeScaling,
            stopPointMs,
            NULL);
        if (res)
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice,
                VoEId(_shared->instance_id(), -1),
                "StartPlayingFileAsMicrophone() failed to start playing file");
            return(-1);
        }
        else
        {
            _shared->transmit_mixer()->SetMixWithMicStatus(mixWithMicrophone);
            return(0);
        }
    }
    else
    {
        // Add file after demultiplexing <=> affects one channel only
        voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
        voe::Channel* channelPtr = ch.channel();
        if (channelPtr == NULL)
        {
            _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                "StartPlayingFileAsMicrophone() failed to locate channel");
            return -1;
        }

        int res = channelPtr->StartPlayingFileAsMicrophone(fileNameUTF8,
                                                           loop,
                                                           format,
                                                           startPointMs,
                                                           volumeScaling,
                                                           stopPointMs,
                                                           NULL);
        if (res)
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice,
                VoEId(_shared->instance_id(), -1),
                "StartPlayingFileAsMicrophone() failed to start playing file");
            return -1;
        }
        else
        {
            channelPtr->SetMixWithMicStatus(mixWithMicrophone);
            return 0;
        }
    }
}

int VoEFileImpl::StartPlayingFileAsMicrophone(int channel,
                                              InStream* stream,
                                              bool mixWithMicrophone,
                                              FileFormats format,
                                              float volumeScaling)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StartPlayingFileAsMicrophone(channel=%d, stream,"
                 " mixWithMicrophone=%d, format=%d, volumeScaling=%5.3f)",
                 channel, mixWithMicrophone, format, volumeScaling);

    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    const uint32_t startPointMs(0);
    const uint32_t stopPointMs(0);

    if (channel == -1)
    {
        int res = _shared->transmit_mixer()->StartPlayingFileAsMicrophone(
            stream,
            format,
            startPointMs,
            volumeScaling,
            stopPointMs,
            NULL);
        if (res)
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice,
                VoEId(_shared->instance_id(), -1),
                "StartPlayingFileAsMicrophone() failed to start "
                "playing stream");
            return(-1);
        }
        else
        {
            _shared->transmit_mixer()->SetMixWithMicStatus(mixWithMicrophone);
            return(0);
        }
    }
    else
    {
        // Add file after demultiplexing <=> affects one channel only
        voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
        voe::Channel* channelPtr = ch.channel();
        if (channelPtr == NULL)
        {
            _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                "StartPlayingFileAsMicrophone() failed to locate channel");
            return -1;
        }

        int res = channelPtr->StartPlayingFileAsMicrophone(
            stream, format, startPointMs, volumeScaling, stopPointMs, NULL);
        if (res)
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice,
                VoEId(_shared->instance_id(), -1),
                "StartPlayingFileAsMicrophone() failed to start "
                "playing stream");
            return -1;
        }
        else
        {
            channelPtr->SetMixWithMicStatus(mixWithMicrophone);
            return 0;
        }
    }
}

int VoEFileImpl::StopPlayingFileAsMicrophone(int channel)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StopPlayingFileAsMicrophone(channel=%d)", channel);
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (channel == -1)
    {
        // Stop adding file before demultiplexing <=> affects all channels
        return _shared->transmit_mixer()->StopPlayingFileAsMicrophone();
    }
    else
    {
        // Stop adding file after demultiplexing <=> affects one channel only
        voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
        voe::Channel* channelPtr = ch.channel();
        if (channelPtr == NULL)
        {
            _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                "StopPlayingFileAsMicrophone() failed to locate channel");
            return -1;
        }
        return channelPtr->StopPlayingFileAsMicrophone();
    }
}

int VoEFileImpl::IsPlayingFileAsMicrophone(int channel)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "IsPlayingFileAsMicrophone(channel=%d)", channel);
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (channel == -1)
    {
        return _shared->transmit_mixer()->IsPlayingFileAsMicrophone();
    }
    else
    {
        // Stop adding file after demultiplexing <=> affects one channel only
        voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
        voe::Channel* channelPtr = ch.channel();
        if (channelPtr == NULL)
        {
            _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                "IsPlayingFileAsMicrophone() failed to locate channel");
            return -1;
        }
        return channelPtr->IsPlayingFileAsMicrophone();
    }
}

int VoEFileImpl::StartRecordingPlayout(
    int channel, const char* fileNameUTF8, CodecInst* compression,
    int maxSizeBytes)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StartRecordingPlayout(channel=%d, fileNameUTF8=%s, "
                 "compression, maxSizeBytes=%d)",
                 channel, fileNameUTF8, maxSizeBytes);
    assert(1024 == FileWrapper::kMaxFileNameSize);

    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (channel == -1)
    {
        return _shared->output_mixer()->StartRecordingPlayout
          (fileNameUTF8, compression);
    }
    else
    {
        // Add file after demultiplexing <=> affects one channel only
        voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
        voe::Channel* channelPtr = ch.channel();
        if (channelPtr == NULL)
        {
            _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                "StartRecordingPlayout() failed to locate channel");
            return -1;
        }
        return channelPtr->StartRecordingPlayout(fileNameUTF8, compression);
    }
}

int VoEFileImpl::StartRecordingPlayout(
    int channel, OutStream* stream, CodecInst* compression)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StartRecordingPlayout(channel=%d, stream, compression)",
                 channel);
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (channel == -1)
    {
        return _shared->output_mixer()->
            StartRecordingPlayout(stream, compression);
    }
    else
    {
        voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
        voe::Channel* channelPtr = ch.channel();
        if (channelPtr == NULL)
        {
            _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                "StartRecordingPlayout() failed to locate channel");
            return -1;
        }
        return channelPtr->StartRecordingPlayout(stream, compression);
    }
}

int VoEFileImpl::StopRecordingPlayout(int channel)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StopRecordingPlayout(channel=%d)", channel);
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (channel == -1)
    {
        return _shared->output_mixer()->StopRecordingPlayout();
    }
    else
    {
        voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
        voe::Channel* channelPtr = ch.channel();
        if (channelPtr == NULL)
        {
            _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                "StopRecordingPlayout() failed to locate channel");
            return -1;
        }
        return channelPtr->StopRecordingPlayout();
    }
}

int VoEFileImpl::StartRecordingMicrophone(
    const char* fileNameUTF8, CodecInst* compression, int maxSizeBytes)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StartRecordingMicrophone(fileNameUTF8=%s, compression, "
                 "maxSizeBytes=%d)", fileNameUTF8, maxSizeBytes);
    assert(1024 == FileWrapper::kMaxFileNameSize);

    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (_shared->transmit_mixer()->StartRecordingMicrophone(fileNameUTF8,
                                                          compression))
    {
        WEBRTC_TRACE(kTraceError, kTraceVoice,
            VoEId(_shared->instance_id(), -1),
            "StartRecordingMicrophone() failed to start recording");
        return -1;
    }
    if (_shared->audio_device()->Recording())
    {
        return 0;
    }
    if (!_shared->ext_recording())
    {
        if (_shared->audio_device()->InitRecording() != 0)
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice,
                VoEId(_shared->instance_id(), -1),
                "StartRecordingMicrophone() failed to initialize recording");
            return -1;
        }
        if (_shared->audio_device()->StartRecording() != 0)
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice,
                VoEId(_shared->instance_id(), -1),
                "StartRecordingMicrophone() failed to start recording");
            return -1;
        }
    }
    return 0;
}

int VoEFileImpl::StartRecordingMicrophone(
    OutStream* stream, CodecInst* compression)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StartRecordingMicrophone(stream, compression)");

    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    if (_shared->transmit_mixer()->StartRecordingMicrophone(stream,
                                                          compression) == -1)
    {
        WEBRTC_TRACE(kTraceError, kTraceVoice,
            VoEId(_shared->instance_id(), -1),
            "StartRecordingMicrophone() failed to start recording");
        return -1;
    }
    if (_shared->audio_device()->Recording())
    {
        return 0;
    }
    if (!_shared->ext_recording())
    {
        if (_shared->audio_device()->InitRecording() != 0)
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice,
                VoEId(_shared->instance_id(), -1),
                "StartRecordingMicrophone() failed to initialize recording");
            return -1;
        }
        if (_shared->audio_device()->StartRecording() != 0)
        {
            WEBRTC_TRACE(kTraceError, kTraceVoice,
                VoEId(_shared->instance_id(), -1),
                "StartRecordingMicrophone() failed to start recording");
            return -1;
        }
    }
    return 0;
}

int VoEFileImpl::StopRecordingMicrophone()
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "StopRecordingMicrophone()");
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    int err = 0;

    // TODO(xians): consider removing Start/StopRecording() in
    // Start/StopRecordingMicrophone() if no channel is recording.
    if (_shared->NumOfSendingChannels() == 0 &&
        _shared->audio_device()->Recording())
    {
        // Stop audio-device recording if no channel is recording
        if (_shared->audio_device()->StopRecording() != 0)
        {
            _shared->SetLastError(VE_CANNOT_STOP_RECORDING, kTraceError,
                "StopRecordingMicrophone() failed to stop recording");
            err = -1;
        }
    }

    if (_shared->transmit_mixer()->StopRecordingMicrophone() != 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceVoice,
                VoEId(_shared->instance_id(), -1),
                "StopRecordingMicrophone() failed to stop recording to mixer");
        err = -1;
    }

    return err;
}

#endif  // #ifdef WEBRTC_VOICE_ENGINE_FILE_API

}  // namespace webrtc
