/*
 *  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
