/*
 *  Copyright (c) 2019 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 "test/pc/e2e/test_peer.h"

#include <string>
#include <utility>

#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "api/scoped_refptr.h"
#include "modules/audio_processing/include/audio_processing.h"

namespace webrtc {
namespace webrtc_pc_e2e {
namespace {

using VideoSubscription = ::webrtc::webrtc_pc_e2e::
    PeerConnectionE2EQualityTestFixture::VideoSubscription;
using VideoConfig =
    ::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::VideoConfig;

class SetRemoteDescriptionCallback
    : public webrtc::SetRemoteDescriptionObserverInterface {
 public:
  void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
    is_called_ = true;
    error_ = error;
  }

  bool is_called() const { return is_called_; }

  webrtc::RTCError error() const { return error_; }

 private:
  bool is_called_ = false;
  webrtc::RTCError error_;
};

}  // namespace

ConfigurableParams TestPeer::configurable_params() const {
  MutexLock lock(&mutex_);
  return configurable_params_;
}

void TestPeer::AddVideoConfig(VideoConfig config) {
  MutexLock lock(&mutex_);
  configurable_params_.video_configs.push_back(std::move(config));
}

void TestPeer::RemoveVideoConfig(absl::string_view stream_label) {
  MutexLock lock(&mutex_);
  bool config_removed = false;
  for (auto it = configurable_params_.video_configs.begin();
       it != configurable_params_.video_configs.end(); ++it) {
    if (*it->stream_label == stream_label) {
      configurable_params_.video_configs.erase(it);
      config_removed = true;
      break;
    }
  }
  RTC_CHECK(config_removed) << *params_.name << ": No video config with label ["
                            << stream_label << "] was found";
}

void TestPeer::SetVideoSubscription(VideoSubscription subscription) {
  MutexLock lock(&mutex_);
  configurable_params_.video_subscription = std::move(subscription);
}

void TestPeer::GetStats(RTCStatsCollectorCallback* callback) {
  pc()->signaling_thread()->PostTask(
      SafeTask(signaling_thread_task_safety_,
               [this, callback]() { pc()->GetStats(callback); }));
}

bool TestPeer::SetRemoteDescription(
    std::unique_ptr<SessionDescriptionInterface> desc,
    std::string* error_out) {
  RTC_CHECK(wrapper_) << "TestPeer is already closed";

  auto observer = rtc::make_ref_counted<SetRemoteDescriptionCallback>();
  // We're assuming (and asserting) that the PeerConnection implementation of
  // SetRemoteDescription is synchronous when called on the signaling thread.
  pc()->SetRemoteDescription(std::move(desc), observer);
  RTC_CHECK(observer->is_called());
  if (!observer->error().ok()) {
    RTC_LOG(LS_ERROR) << *params_.name << ": Failed to set remote description: "
                      << observer->error().message();
    if (error_out) {
      *error_out = observer->error().message();
    }
  }
  return observer->error().ok();
}

bool TestPeer::AddIceCandidates(
    std::vector<std::unique_ptr<IceCandidateInterface>> candidates) {
  RTC_CHECK(wrapper_) << "TestPeer is already closed";
  bool success = true;
  for (auto& candidate : candidates) {
    if (!pc()->AddIceCandidate(candidate.get())) {
      std::string candidate_str;
      bool res = candidate->ToString(&candidate_str);
      RTC_CHECK(res);
      RTC_LOG(LS_ERROR) << "Failed to add ICE candidate, candidate_str="
                        << candidate_str;
      success = false;
    } else {
      remote_ice_candidates_.push_back(std::move(candidate));
    }
  }
  return success;
}

void TestPeer::Close() {
  signaling_thread_task_safety_->SetNotAlive();
  wrapper_->pc()->Close();
  remote_ice_candidates_.clear();
  audio_processing_ = nullptr;
  video_sources_.clear();
  wrapper_ = nullptr;
  worker_thread_ = nullptr;
}

TestPeer::TestPeer(
    rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
    rtc::scoped_refptr<PeerConnectionInterface> pc,
    std::unique_ptr<MockPeerConnectionObserver> observer,
    Params params,
    ConfigurableParams configurable_params,
    std::vector<PeerConfigurerImpl::VideoSource> video_sources,
    rtc::scoped_refptr<AudioProcessing> audio_processing,
    std::unique_ptr<rtc::Thread> worker_thread)
    : params_(std::move(params)),
      configurable_params_(std::move(configurable_params)),
      worker_thread_(std::move(worker_thread)),
      wrapper_(std::make_unique<PeerConnectionWrapper>(std::move(pc_factory),
                                                       std::move(pc),
                                                       std::move(observer))),
      video_sources_(std::move(video_sources)),
      audio_processing_(audio_processing) {
  signaling_thread_task_safety_ = PendingTaskSafetyFlag::CreateDetached();
}

}  // namespace webrtc_pc_e2e
}  // namespace webrtc
