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

#include <memory>

#include "test/network/network_emulation_manager.h"

namespace webrtc {
namespace test {
namespace {
constexpr size_t kIcePacketSize = 400;
constexpr size_t kSdpPacketSize = 1200;

struct IceMessage {
  IceMessage() = default;
  explicit IceMessage(const IceCandidateInterface* candidate)
      : sdp_mid(candidate->sdp_mid()),
        sdp_mline_index(candidate->sdp_mline_index()) {
    RTC_CHECK(candidate->ToString(&sdp_line));
  }
  std::unique_ptr<IceCandidateInterface> AsCandidate() const {
    SdpParseError err;
    std::unique_ptr<IceCandidateInterface> candidate(
        CreateIceCandidate(sdp_mid, sdp_mline_index, sdp_line, &err));
    RTC_CHECK(candidate) << "Failed to parse: \"" << err.line
                         << "\". Reason: " << err.description;
    return candidate;
  }
  std::string sdp_mid;
  int sdp_mline_index;
  std::string sdp_line;
};

void StartIceSignalingForRoute(PeerScenarioClient* caller,
                               PeerScenarioClient* callee,
                               TrafficRoute* send_route) {
  caller->handlers()->on_ice_candidate.push_back(
      [=](const IceCandidateInterface* candidate) {
        IceMessage msg(candidate);
        send_route->NetworkDelayedAction(kIcePacketSize, [callee, msg]() {
          callee->thread()->PostTask(RTC_FROM_HERE, [callee, msg]() {
            callee->AddIceCandidate(msg.AsCandidate());
          });
        });
      });
}

void StartSdpNegotiation(
    PeerScenarioClient* caller,
    PeerScenarioClient* callee,
    TrafficRoute* send_route,
    TrafficRoute* ret_route,
    std::function<void(SessionDescriptionInterface* offer)> munge_offer,
    std::function<void(SessionDescriptionInterface*)> modify_offer,
    std::function<void(const SessionDescriptionInterface&)> exchange_finished) {
  caller->CreateAndSetSdp(munge_offer, [=](std::string sdp_offer) {
    if (modify_offer) {
      auto offer = CreateSessionDescription(SdpType::kOffer, sdp_offer);
      modify_offer(offer.get());
      RTC_CHECK(offer->ToString(&sdp_offer));
    }
    send_route->NetworkDelayedAction(kSdpPacketSize, [=] {
      callee->SetSdpOfferAndGetAnswer(sdp_offer, [=](std::string answer) {
        ret_route->NetworkDelayedAction(kSdpPacketSize, [=] {
          caller->SetSdpAnswer(std::move(answer), std::move(exchange_finished));
        });
      });
    });
  });
}
}  // namespace

SignalingRoute::SignalingRoute(PeerScenarioClient* caller,
                               PeerScenarioClient* callee,
                               TrafficRoute* send_route,
                               TrafficRoute* ret_route)
    : caller_(caller),
      callee_(callee),
      send_route_(send_route),
      ret_route_(ret_route) {}

void SignalingRoute::StartIceSignaling() {
  StartIceSignalingForRoute(caller_, callee_, send_route_);
  StartIceSignalingForRoute(callee_, caller_, ret_route_);
}

void SignalingRoute::NegotiateSdp(
    std::function<void(SessionDescriptionInterface*)> munge_offer,
    std::function<void(SessionDescriptionInterface*)> modify_offer,
    std::function<void(const SessionDescriptionInterface&)> exchange_finished) {
  StartSdpNegotiation(caller_, callee_, send_route_, ret_route_, munge_offer,
                      modify_offer, exchange_finished);
}

void SignalingRoute::NegotiateSdp(
    std::function<void(SessionDescriptionInterface*)> modify_offer,
    std::function<void(const SessionDescriptionInterface&)> exchange_finished) {
  NegotiateSdp({}, modify_offer, exchange_finished);
}

void SignalingRoute::NegotiateSdp(
    std::function<void(const SessionDescriptionInterface&)> exchange_finished) {
  NegotiateSdp({}, {}, exchange_finished);
}

}  // namespace test
}  // namespace webrtc
