/*
 *  Copyright 2016 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 API_TEST_MOCK_PEERCONNECTIONINTERFACE_H_
#define API_TEST_MOCK_PEERCONNECTIONINTERFACE_H_

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

#include "api/peer_connection_interface.h"
#include "api/sctp_transport_interface.h"
#include "test/gmock.h"

namespace webrtc {

class MockPeerConnectionInterface
    : public rtc::RefCountedObject<webrtc::PeerConnectionInterface> {
 public:
  // PeerConnectionInterface
  MOCK_METHOD0(local_streams, rtc::scoped_refptr<StreamCollectionInterface>());
  MOCK_METHOD0(remote_streams, rtc::scoped_refptr<StreamCollectionInterface>());
  MOCK_METHOD1(AddStream, bool(MediaStreamInterface*));
  MOCK_METHOD1(RemoveStream, void(MediaStreamInterface*));
  MOCK_METHOD2(AddTrack,
               RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>>(
                   rtc::scoped_refptr<MediaStreamTrackInterface>,
                   const std::vector<std::string>&));
  MOCK_METHOD2(AddTrack,
               rtc::scoped_refptr<RtpSenderInterface>(
                   MediaStreamTrackInterface*,
                   std::vector<MediaStreamInterface*>));
  MOCK_METHOD1(RemoveTrack, bool(RtpSenderInterface*));
  MOCK_METHOD1(AddTransceiver,
               RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>(
                   rtc::scoped_refptr<MediaStreamTrackInterface>));
  MOCK_METHOD2(AddTransceiver,
               RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>(
                   rtc::scoped_refptr<MediaStreamTrackInterface>,
                   const RtpTransceiverInit&));
  MOCK_METHOD1(AddTransceiver,
               RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>(
                   cricket::MediaType));
  MOCK_METHOD2(AddTransceiver,
               RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>(
                   cricket::MediaType,
                   const RtpTransceiverInit&));
  MOCK_METHOD2(CreateSender,
               rtc::scoped_refptr<RtpSenderInterface>(const std::string&,
                                                      const std::string&));
  MOCK_CONST_METHOD0(GetSenders,
                     std::vector<rtc::scoped_refptr<RtpSenderInterface>>());
  MOCK_CONST_METHOD0(GetReceivers,
                     std::vector<rtc::scoped_refptr<RtpReceiverInterface>>());
  MOCK_CONST_METHOD0(
      GetTransceivers,
      std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>());
  MOCK_METHOD3(GetStats,
               bool(StatsObserver*,
                    MediaStreamTrackInterface*,
                    StatsOutputLevel));
  MOCK_METHOD1(GetStats, void(RTCStatsCollectorCallback*));
  MOCK_METHOD2(GetStats,
               void(rtc::scoped_refptr<RtpSenderInterface>,
                    rtc::scoped_refptr<RTCStatsCollectorCallback>));
  MOCK_METHOD2(GetStats,
               void(rtc::scoped_refptr<RtpReceiverInterface>,
                    rtc::scoped_refptr<RTCStatsCollectorCallback>));
  MOCK_METHOD0(ClearStatsCache, void());
  MOCK_CONST_METHOD0(GetSctpTransport,
                     rtc::scoped_refptr<SctpTransportInterface>());
  MOCK_METHOD2(
      CreateDataChannel,
      rtc::scoped_refptr<DataChannelInterface>(const std::string&,
                                               const DataChannelInit*));
  MOCK_CONST_METHOD0(local_description, const SessionDescriptionInterface*());
  MOCK_CONST_METHOD0(remote_description, const SessionDescriptionInterface*());
  MOCK_CONST_METHOD0(current_local_description,
                     const SessionDescriptionInterface*());
  MOCK_CONST_METHOD0(current_remote_description,
                     const SessionDescriptionInterface*());
  MOCK_CONST_METHOD0(pending_local_description,
                     const SessionDescriptionInterface*());
  MOCK_CONST_METHOD0(pending_remote_description,
                     const SessionDescriptionInterface*());
  MOCK_METHOD2(CreateOffer,
               void(CreateSessionDescriptionObserver*,
                    const RTCOfferAnswerOptions&));
  MOCK_METHOD2(CreateAnswer,
               void(CreateSessionDescriptionObserver*,
                    const RTCOfferAnswerOptions&));
  MOCK_METHOD2(SetLocalDescription,
               void(SetSessionDescriptionObserver*,
                    SessionDescriptionInterface*));
  MOCK_METHOD2(SetRemoteDescription,
               void(SetSessionDescriptionObserver*,
                    SessionDescriptionInterface*));
  MOCK_METHOD2(SetRemoteDescription,
               void(std::unique_ptr<SessionDescriptionInterface>,
                    rtc::scoped_refptr<SetRemoteDescriptionObserverInterface>));
  MOCK_METHOD0(GetConfiguration, PeerConnectionInterface::RTCConfiguration());
  MOCK_METHOD2(SetConfiguration,
               bool(const PeerConnectionInterface::RTCConfiguration&,
                    RTCError*));
  MOCK_METHOD1(SetConfiguration,
               bool(const PeerConnectionInterface::RTCConfiguration&));
  MOCK_METHOD1(AddIceCandidate, bool(const IceCandidateInterface*));
  MOCK_METHOD1(RemoveIceCandidates,
               bool(const std::vector<cricket::Candidate>&));
  MOCK_METHOD1(SetBitrate, RTCError(const BitrateSettings&));
  MOCK_METHOD1(SetBitrate, RTCError(const BitrateParameters&));
  MOCK_METHOD1(SetBitrateAllocationStrategy,
               void(std::unique_ptr<rtc::BitrateAllocationStrategy>));
  MOCK_METHOD1(SetAudioPlayout, void(bool));
  MOCK_METHOD1(SetAudioRecording, void(bool));
  MOCK_METHOD0(signaling_state, SignalingState());
  MOCK_METHOD0(ice_connection_state, IceConnectionState());
  MOCK_METHOD0(ice_gathering_state, IceGatheringState());
  MOCK_METHOD2(StartRtcEventLog, bool(rtc::PlatformFile, int64_t));
  MOCK_METHOD2(StartRtcEventLog,
               bool(std::unique_ptr<RtcEventLogOutput>, int64_t));
  MOCK_METHOD0(StopRtcEventLog, void());
  MOCK_METHOD0(Close, void());
};

}  // namespace webrtc

#endif  // API_TEST_MOCK_PEERCONNECTIONINTERFACE_H_
