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

#ifndef PC_PEER_CONNECTION_WRAPPER_H_
#define PC_PEER_CONNECTION_WRAPPER_H_

#include <memory>
#include <string>
#include <vector>

#include "absl/types/optional.h"
#include "api/data_channel_interface.h"
#include "api/function_view.h"
#include "api/jsep.h"
#include "api/media_stream_interface.h"
#include "api/media_types.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtp_sender_interface.h"
#include "api/rtp_transceiver_interface.h"
#include "api/scoped_refptr.h"
#include "api/stats/rtc_stats_report.h"
#include "pc/test/mock_peer_connection_observers.h"

namespace webrtc {

// Class that wraps a PeerConnection so that it is easier to use in unit tests.
// Namely, gives a synchronous API for the event-callback-based API of
// PeerConnection and provides an observer object that stores information from
// PeerConnectionObserver callbacks.
//
// This is intended to be subclassed if additional information needs to be
// stored with the PeerConnection (e.g., fake PeerConnection parameters so that
// tests can be written against those interactions). The base
// PeerConnectionWrapper should only have helper methods that are broadly
// useful. More specific helper methods should be created in the test-specific
// subclass.
//
// The wrapper is intended to be constructed by specialized factory methods on
// a test fixture class then used as a local variable in each test case.
class PeerConnectionWrapper {
 public:
  // Constructs a PeerConnectionWrapper from the given PeerConnection.
  // The given PeerConnectionFactory should be the factory that created the
  // PeerConnection and the MockPeerConnectionObserver should be the observer
  // that is watching the PeerConnection.
  PeerConnectionWrapper(
      rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
      rtc::scoped_refptr<PeerConnectionInterface> pc,
      std::unique_ptr<MockPeerConnectionObserver> observer);
  virtual ~PeerConnectionWrapper();

  PeerConnectionFactoryInterface* pc_factory();
  PeerConnectionInterface* pc();
  MockPeerConnectionObserver* observer();

  // Calls the underlying PeerConnection's CreateOffer method and returns the
  // resulting SessionDescription once it is available. If the method call
  // failed, null is returned.
  std::unique_ptr<SessionDescriptionInterface> CreateOffer(
      const PeerConnectionInterface::RTCOfferAnswerOptions& options,
      std::string* error_out = nullptr);
  // Calls CreateOffer with default options.
  std::unique_ptr<SessionDescriptionInterface> CreateOffer();
  // Calls CreateOffer and sets a copy of the offer as the local description.
  std::unique_ptr<SessionDescriptionInterface> CreateOfferAndSetAsLocal(
      const PeerConnectionInterface::RTCOfferAnswerOptions& options);
  // Calls CreateOfferAndSetAsLocal with default options.
  std::unique_ptr<SessionDescriptionInterface> CreateOfferAndSetAsLocal();

  // Calls the underlying PeerConnection's CreateAnswer method and returns the
  // resulting SessionDescription once it is available. If the method call
  // failed, null is returned.
  std::unique_ptr<SessionDescriptionInterface> CreateAnswer(
      const PeerConnectionInterface::RTCOfferAnswerOptions& options,
      std::string* error_out = nullptr);
  // Calls CreateAnswer with the default options.
  std::unique_ptr<SessionDescriptionInterface> CreateAnswer();
  // Calls CreateAnswer and sets a copy of the offer as the local description.
  std::unique_ptr<SessionDescriptionInterface> CreateAnswerAndSetAsLocal(
      const PeerConnectionInterface::RTCOfferAnswerOptions& options);
  // Calls CreateAnswerAndSetAsLocal with default options.
  std::unique_ptr<SessionDescriptionInterface> CreateAnswerAndSetAsLocal();
  std::unique_ptr<SessionDescriptionInterface> CreateRollback();

  // Calls the underlying PeerConnection's SetLocalDescription method with the
  // given session description and waits for the success/failure response.
  // Returns true if the description was successfully set.
  bool SetLocalDescription(std::unique_ptr<SessionDescriptionInterface> desc,
                           std::string* error_out = nullptr);
  // Calls the underlying PeerConnection's SetRemoteDescription method with the
  // given session description and waits for the success/failure response.
  // Returns true if the description was successfully set.
  bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc,
                            std::string* error_out = nullptr);
  bool SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc,
                            RTCError* error_out);

  // Does a round of offer/answer with the local PeerConnectionWrapper
  // generating the offer and the given PeerConnectionWrapper generating the
  // answer.
  // Equivalent to:
  // 1. this->CreateOffer(offer_options)
  // 2. this->SetLocalDescription(offer)
  // 3. answerer->SetRemoteDescription(offer)
  // 4. answerer->CreateAnswer(answer_options)
  // 5. answerer->SetLocalDescription(answer)
  // 6. this->SetRemoteDescription(answer)
  // Returns true if all steps succeed, false otherwise.
  // Suggested usage:
  //   ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
  bool ExchangeOfferAnswerWith(PeerConnectionWrapper* answerer);
  bool ExchangeOfferAnswerWith(
      PeerConnectionWrapper* answerer,
      const PeerConnectionInterface::RTCOfferAnswerOptions& offer_options,
      const PeerConnectionInterface::RTCOfferAnswerOptions& answer_options);

  // The following are wrappers for the underlying PeerConnection's
  // AddTransceiver method. They return the result of calling AddTransceiver
  // with the given arguments, DCHECKing if there is an error.
  rtc::scoped_refptr<RtpTransceiverInterface> AddTransceiver(
      cricket::MediaType media_type);
  rtc::scoped_refptr<RtpTransceiverInterface> AddTransceiver(
      cricket::MediaType media_type,
      const RtpTransceiverInit& init);
  rtc::scoped_refptr<RtpTransceiverInterface> AddTransceiver(
      rtc::scoped_refptr<MediaStreamTrackInterface> track);
  rtc::scoped_refptr<RtpTransceiverInterface> AddTransceiver(
      rtc::scoped_refptr<MediaStreamTrackInterface> track,
      const RtpTransceiverInit& init);

  // Returns a new dummy audio track with the given label.
  rtc::scoped_refptr<AudioTrackInterface> CreateAudioTrack(
      const std::string& label);

  // Returns a new dummy video track with the given label.
  rtc::scoped_refptr<VideoTrackInterface> CreateVideoTrack(
      const std::string& label);

  // Wrapper for the underlying PeerConnection's AddTrack method. DCHECKs if
  // AddTrack fails.
  rtc::scoped_refptr<RtpSenderInterface> AddTrack(
      rtc::scoped_refptr<MediaStreamTrackInterface> track,
      const std::vector<std::string>& stream_ids = {});

  rtc::scoped_refptr<RtpSenderInterface> AddTrack(
      rtc::scoped_refptr<MediaStreamTrackInterface> track,
      const std::vector<std::string>& stream_ids,
      const std::vector<RtpEncodingParameters>& init_send_encodings);

  // Calls the underlying PeerConnection's AddTrack method with an audio media
  // stream track not bound to any source.
  rtc::scoped_refptr<RtpSenderInterface> AddAudioTrack(
      const std::string& track_label,
      const std::vector<std::string>& stream_ids = {});

  // Calls the underlying PeerConnection's AddTrack method with a video media
  // stream track fed by a FakeVideoTrackSource.
  rtc::scoped_refptr<RtpSenderInterface> AddVideoTrack(
      const std::string& track_label,
      const std::vector<std::string>& stream_ids = {});

  // Calls the underlying PeerConnection's CreateDataChannel method with default
  // initialization parameters.
  rtc::scoped_refptr<DataChannelInterface> CreateDataChannel(
      const std::string& label,
      const absl::optional<DataChannelInit>& config = absl::nullopt);

  // Returns the signaling state of the underlying PeerConnection.
  PeerConnectionInterface::SignalingState signaling_state();

  // Returns true if ICE has finished gathering candidates.
  bool IsIceGatheringDone();

  // Returns true if ICE has established a connection.
  bool IsIceConnected();

  // Calls GetStats() on the underlying PeerConnection and returns the resulting
  // report. If GetStats() fails, this method returns null and fails the test.
  rtc::scoped_refptr<const RTCStatsReport> GetStats();

 private:
  std::unique_ptr<SessionDescriptionInterface> CreateSdp(
      rtc::FunctionView<void(CreateSessionDescriptionObserver*)> fn,
      std::string* error_out);
  bool SetSdp(rtc::FunctionView<void(SetSessionDescriptionObserver*)> fn,
              std::string* error_out);

  rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
  std::unique_ptr<MockPeerConnectionObserver> observer_;
  rtc::scoped_refptr<PeerConnectionInterface> pc_;
};

}  // namespace webrtc

#endif  // PC_PEER_CONNECTION_WRAPPER_H_
