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

// Refer to kUsage below for a description.

#include "gflags/gflags.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/system_wrappers/interface/sleep.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/test/channel_transport/include/channel_transport.h"
#include "webrtc/test/testsupport/trace_to_stderr.h"
#include "webrtc/tools/agc/agc_manager.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/voice_engine/include/voe_audio_processing.h"
#include "webrtc/voice_engine/include/voe_base.h"
#include "webrtc/voice_engine/include/voe_codec.h"
#include "webrtc/voice_engine/include/voe_external_media.h"
#include "webrtc/voice_engine/include/voe_file.h"
#include "webrtc/voice_engine/include/voe_hardware.h"
#include "webrtc/voice_engine/include/voe_network.h"
#include "webrtc/voice_engine/include/voe_volume_control.h"

DEFINE_bool(codecs, false, "print out available codecs");
DEFINE_int32(pt, 120, "codec payload type (defaults to opus/48000/2)");
DEFINE_bool(legacy_agc,
            false,
            "use the legacy AGC in 'serial' mode, or as the first voice "
            "engine's AGC in parallel mode");
DEFINE_bool(parallel,
            false,
            "run new and legacy AGCs in parallel, with left- and right-panning "
            "respectively. Not compatible with -aec.");
DEFINE_bool(devices, false, "print out capture devices and indexes to be used "
                            "with the capture flags");
DEFINE_int32(capture1, 0, "capture device index for the first voice engine");
DEFINE_int32(capture2, 0, "capture device index for second voice engine");
DEFINE_int32(render1, 0, "render device index for first voice engine");
DEFINE_int32(render2, 0, "render device index for second voice engine");
DEFINE_bool(aec,
            false,
            "runs two voice engines in parallel, with the first playing out a "
            "file and sending its captured signal to the second voice engine. "
            "Also enables echo cancellation.");
DEFINE_bool(ns, true, "enable noise suppression");
DEFINE_bool(highpass, true, "enable high pass filter");
DEFINE_string(filename, "", "filename for the -aec mode");

namespace webrtc {
namespace {

const char kUsage[] =
    "\nWithout additional flags, sets up a simple VoiceEngine loopback call\n"
    "with the default audio devices and runs forever.\n"

    "It can also run the new and legacy AGCs in parallel, panned to\n"
    "opposite stereo channels on the default render device. The capture\n"
    "devices for each can be selected (recommended, because otherwise they\n"
    "will fight for the level on the same device).\n\n"

    "Lastly, it can be used for local AEC testing. In this mode, the first\n"
    "voice engine plays out a file over the selected render device (normally\n"
    "loudspeakers) and records from the selected capture device. The second\n"
    "voice engine receives the capture signal and plays it out over the\n"
    "selected render device (normally headphones). This allows the user to\n"
    "test an echo scenario with the first voice engine, while monitoring the\n"
    "result with the second.";

class AgcVoiceEngine {
 public:
  enum Pan {
    NoPan,
    PanLeft,
    PanRight
  };

  AgcVoiceEngine(bool legacy_agc,
                 int tx_port,
                 int rx_port,
                 int capture_idx,
                 int render_idx)
      : voe_(VoiceEngine::Create()),
        base_(VoEBase::GetInterface(voe_)),
        hardware_(VoEHardware::GetInterface(voe_)),
        codec_(VoECodec::GetInterface(voe_)),
        channel_(-1),
        capture_idx_(capture_idx),
        render_idx_(render_idx) {
    SetUp(legacy_agc, tx_port, rx_port);
  }

  ~AgcVoiceEngine() {
    TearDown();
  }

  void SetUp(bool legacy_agc, int tx_port, int rx_port) {
    VoEAudioProcessing* audio = VoEAudioProcessing::GetInterface(voe_);
    VoENetwork* network = VoENetwork::GetInterface(voe_);
    {
      webrtc::Config config;
      config.Set<ExperimentalAgc>(new ExperimentalAgc(!legacy_agc));
      AudioProcessing* audioproc = AudioProcessing::Create(config);
      CHECK_EQ(0, base_->Init(nullptr, audioproc));
      // Set this stuff after Init, to override the default voice engine
      // settings.
      audioproc->gain_control()->Enable(true);
      audioproc->high_pass_filter()->Enable(FLAGS_highpass);
      audioproc->noise_suppression()->Enable(FLAGS_ns);
      audioproc->echo_cancellation()->Enable(FLAGS_aec);
    }
    channel_ = base_->CreateChannel();
    CHECK_NE(-1, channel_);

    channel_transport_.reset(
        new test::VoiceChannelTransport(network, channel_));
    CHECK_EQ(0, channel_transport_->SetSendDestination("127.0.0.1", tx_port));
    CHECK_EQ(0, channel_transport_->SetLocalReceiver(rx_port));

    CHECK_EQ(0, hardware_->SetRecordingDevice(capture_idx_));
    CHECK_EQ(0, hardware_->SetPlayoutDevice(render_idx_));

    CodecInst codec_params = {};
    bool codec_found = false;
    for (int i = 0; i < codec_->NumOfCodecs(); i++) {
      CHECK_EQ(0, codec_->GetCodec(i, codec_params));
      if (FLAGS_pt == codec_params.pltype) {
        codec_found = true;
        break;
      }
    }
    CHECK(codec_found);
    CHECK_EQ(0, codec_->SetSendCodec(channel_, codec_params));

    audio->Release();
    network->Release();
  }

  void TearDown() {
    Stop();
    channel_transport_.reset(nullptr);
    CHECK_EQ(0, base_->DeleteChannel(channel_));
    CHECK_EQ(0, base_->Terminate());
    hardware_->Release();
    base_->Release();
    codec_->Release();
    CHECK(VoiceEngine::Delete(voe_));
  }

  void PrintDevices() {
    int num_devices = 0;
    char device_name[128] = {0};
    char guid[128] = {0};
    CHECK_EQ(0, hardware_->GetNumOfRecordingDevices(num_devices));
    printf("Capture devices:\n");
    for (int i = 0; i < num_devices; i++) {
      CHECK_EQ(0, hardware_->GetRecordingDeviceName(i, device_name, guid));
      printf("%d: %s\n", i, device_name);
    }
    CHECK_EQ(0, hardware_->GetNumOfPlayoutDevices(num_devices));
    printf("Render devices:\n");
    for (int i = 0; i < num_devices; i++) {
      CHECK_EQ(0, hardware_->GetPlayoutDeviceName(i, device_name, guid));
      printf("%d: %s\n", i, device_name);
    }
  }

  void PrintCodecs() {
    CodecInst params = {0};
    printf("Codecs:\n");
    for (int i = 0; i < codec_->NumOfCodecs(); i++) {
      CHECK_EQ(0, codec_->GetCodec(i, params));
      printf("%d %s/%d/%d\n", params.pltype, params.plname, params.plfreq,
             params.channels);
    }
  }

  void StartSending() { CHECK_EQ(0, base_->StartSend(channel_)); }

  void StartPlaying(Pan pan, const std::string& filename) {
    VoEVolumeControl* volume = VoEVolumeControl::GetInterface(voe_);
    VoEFile* file = VoEFile::GetInterface(voe_);
    if (pan == PanLeft) {
      volume->SetOutputVolumePan(channel_, 1, 0);
    } else if (pan == PanRight) {
      volume->SetOutputVolumePan(channel_, 0, 1);
    }
    if (filename != "") {
      printf("playing file\n");
      CHECK_EQ(
          0, file->StartPlayingFileLocally(channel_, filename.c_str(), true,
                                           kFileFormatPcm16kHzFile, 1.0, 0, 0));
    }
    CHECK_EQ(0, base_->StartReceive(channel_));
    CHECK_EQ(0, base_->StartPlayout(channel_));
    volume->Release();
    file->Release();
  }

  void Stop() {
    CHECK_EQ(0, base_->StopSend(channel_));
    CHECK_EQ(0, base_->StopPlayout(channel_));
  }

 private:
  VoiceEngine* voe_;
  VoEBase* base_;
  VoEHardware* hardware_;
  VoECodec* codec_;
  int channel_;
  int capture_idx_;
  int render_idx_;
  rtc::scoped_ptr<test::VoiceChannelTransport> channel_transport_;
};

void RunHarness() {
  rtc::scoped_ptr<AgcVoiceEngine> voe1(new AgcVoiceEngine(
      FLAGS_legacy_agc, 2000, 2000, FLAGS_capture1, FLAGS_render1));
  rtc::scoped_ptr<AgcVoiceEngine> voe2;
  if (FLAGS_parallel) {
    voe2.reset(new AgcVoiceEngine(!FLAGS_legacy_agc, 3000, 3000, FLAGS_capture2,
                                  FLAGS_render2));
    voe1->StartPlaying(AgcVoiceEngine::PanLeft, "");
    voe1->StartSending();
    voe2->StartPlaying(AgcVoiceEngine::PanRight, "");
    voe2->StartSending();
  } else if (FLAGS_aec) {
    voe1.reset(new AgcVoiceEngine(FLAGS_legacy_agc, 2000, 4242, FLAGS_capture1,
                                  FLAGS_render1));
    voe2.reset(new AgcVoiceEngine(!FLAGS_legacy_agc, 4242, 2000, FLAGS_capture2,
                                  FLAGS_render2));
    voe1->StartPlaying(AgcVoiceEngine::NoPan, FLAGS_filename);
    voe1->StartSending();
    voe2->StartPlaying(AgcVoiceEngine::NoPan, "");
  } else {
    voe1->StartPlaying(AgcVoiceEngine::NoPan, "");
    voe1->StartSending();
  }

  // Run forever...
  SleepMs(0x7fffffff);
}

void PrintDevices() {
  AgcVoiceEngine device_voe(false, 4242, 4242, 0, 0);
  device_voe.PrintDevices();
}

void PrintCodecs() {
  AgcVoiceEngine codec_voe(false, 4242, 4242, 0, 0);
  codec_voe.PrintCodecs();
}

}  // namespace
}  // namespace webrtc

int main(int argc, char** argv) {
  google::SetUsageMessage(webrtc::kUsage);
  google::ParseCommandLineFlags(&argc, &argv, true);
  webrtc::test::TraceToStderr trace_to_stderr;

  if (FLAGS_parallel && FLAGS_aec) {
    printf("-parallel and -aec are not compatible\n");
    return 1;
  }
  if (FLAGS_devices) {
    webrtc::PrintDevices();
  }
  if (FLAGS_codecs) {
    webrtc::PrintCodecs();
  }
  if (!FLAGS_devices && !FLAGS_codecs) {
    webrtc::RunHarness();
  }
  return 0;
}
