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

#include "webrtc/system_wrappers/interface/critical_section_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 {

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

#ifdef WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API

VoEExternalMediaImpl::VoEExternalMediaImpl(voe::SharedData* shared)
    :
#ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
    playout_delay_ms_(0),
#endif
    shared_(shared)
{
    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(shared_->instance_id(), -1),
                 "VoEExternalMediaImpl() - ctor");
}

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

int VoEExternalMediaImpl::RegisterExternalMediaProcessing(
    int channel,
    ProcessingTypes type,
    VoEMediaProcess& processObject)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(shared_->instance_id(), -1),
                 "RegisterExternalMediaProcessing(channel=%d, type=%d, "
                 "processObject=0x%x)", channel, type, &processObject);
    if (!shared_->statistics().Initialized())
    {
        shared_->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    switch (type)
    {
        case kPlaybackPerChannel:
        case kRecordingPerChannel:
        {
            voe::ChannelOwner ch =
                shared_->channel_manager().GetChannel(channel);
            voe::Channel* channelPtr = ch.channel();
            if (channelPtr == NULL)
            {
                shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                    "RegisterExternalMediaProcessing() failed to locate "
                    "channel");
                return -1;
            }
            return channelPtr->RegisterExternalMediaProcessing(type,
                                                               processObject);
        }
        case kPlaybackAllChannelsMixed:
        {
            return shared_->output_mixer()->RegisterExternalMediaProcessing(
                processObject);
        }
        case kRecordingAllChannelsMixed:
        case kRecordingPreprocessing:
        {
            return shared_->transmit_mixer()->RegisterExternalMediaProcessing(
                &processObject, type);
        }
    }
    return -1;
}

int VoEExternalMediaImpl::DeRegisterExternalMediaProcessing(
    int channel,
    ProcessingTypes type)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(shared_->instance_id(), -1),
                 "DeRegisterExternalMediaProcessing(channel=%d)", channel);
    if (!shared_->statistics().Initialized())
    {
        shared_->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    switch (type)
    {
        case kPlaybackPerChannel:
        case kRecordingPerChannel:
        {
            voe::ChannelOwner ch =
                shared_->channel_manager().GetChannel(channel);
            voe::Channel* channelPtr = ch.channel();
            if (channelPtr == NULL)
            {
                shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
                    "RegisterExternalMediaProcessing() "
                    "failed to locate channel");
                return -1;
            }
            return channelPtr->DeRegisterExternalMediaProcessing(type);
        }
        case kPlaybackAllChannelsMixed:
        {
            return shared_->output_mixer()->
                DeRegisterExternalMediaProcessing();
        }
        case kRecordingAllChannelsMixed:
        case kRecordingPreprocessing:
        {
            return shared_->transmit_mixer()->
                DeRegisterExternalMediaProcessing(type);
        }
    }
    return -1;
}

int VoEExternalMediaImpl::GetAudioFrame(int channel, int desired_sample_rate_hz,
                                        AudioFrame* frame) {
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
                 VoEId(shared_->instance_id(), channel),
                 "GetAudioFrame(channel=%d, desired_sample_rate_hz=%d)",
                 channel, desired_sample_rate_hz);
    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,
            "GetAudioFrame() failed to locate channel");
        return -1;
    }
    if (!channelPtr->ExternalMixing()) {
        shared_->SetLastError(VE_INVALID_OPERATION, kTraceError,
            "GetAudioFrame() was called on channel that is not"
            " externally mixed.");
        return -1;
    }
    if (!channelPtr->Playing()) {
        shared_->SetLastError(VE_INVALID_OPERATION, kTraceError,
            "GetAudioFrame() was called on channel that is not playing.");
        return -1;
    }
    if (desired_sample_rate_hz == -1) {
          shared_->SetLastError(VE_BAD_ARGUMENT, kTraceError,
              "GetAudioFrame() was called with bad sample rate.");
          return -1;
    }
    frame->sample_rate_hz_ = desired_sample_rate_hz == 0 ? -1 :
                             desired_sample_rate_hz;
    return channelPtr->GetAudioFrame(channel, *frame);
}

int VoEExternalMediaImpl::SetExternalMixing(int channel, bool enable) {
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
                 VoEId(shared_->instance_id(), channel),
                 "SetExternalMixing(channel=%d, enable=%d)", channel, enable);
    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,
            "SetExternalMixing() failed to locate channel");
        return -1;
    }
    return channelPtr->SetExternalMixing(enable);
}

#endif  // WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API

}  // namespace webrtc
