/*
 *  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.
 */
#ifndef TEST_PEER_SCENARIO_PEER_SCENARIO_H_
#define TEST_PEER_SCENARIO_PEER_SCENARIO_H_

// The peer connection scenario test framework enables writing end to end unit
// tests on the peer connection level. It's similar to the Scenario test but
// uses the full stack, including SDP and ICE negotiation. This ensures that
// features work end to end. It's also diffferent from the other tests on peer
// connection level in that it does not rely on any mocks or fakes other than
// for media input and networking. Additionally it provides direct access to the
// underlying peer connection class.

#include <list>
#include <vector>

#include "test/gtest.h"
#include "test/logging/log_writer.h"
#include "test/network/network_emulation_manager.h"
#include "test/peer_scenario/peer_scenario_client.h"
#include "test/peer_scenario/signaling_route.h"
#include "test/scenario/stats_collection.h"
#include "test/scenario/video_frame_matcher.h"

namespace webrtc {
namespace test {

// The PeerScenario class represents a PeerConnection simulation scenario. The
// main purpose is to maintain ownership and ensure safe destruction order of
// clients and network emulation. Additionally it reduces the amount of boiler
// plate requited for some actions. For example usage see the existing tests
// using this class. Note that it should be used from a single calling thread.
// This thread will also be assigned as the signaling thread for all peer
// connections that are created. This means that the process methods must be
// used when waiting to ensure that messages are processed on the signaling
// thread.
class PeerScenario {
 public:
  // The name is used for log output when those are enabled by the --peer_logs
  // command line flag. Optionally, the TestInfo struct available in gtest can
  // be used to automatically generate a path based on the test name.
  explicit PeerScenario(const testing::TestInfo& test_info);
  explicit PeerScenario(std::string file_name);
  explicit PeerScenario(
      std::unique_ptr<LogWriterFactoryInterface> log_writer_manager);

  NetworkEmulationManagerImpl* net() { return &net_; }
  rtc::Thread* thread() { return signaling_thread_; }

  // Creates a client wrapping a peer connection conforming to the given config.
  // The client  will share the signaling thread with the scenario. To maintain
  // control of destruction order, ownership is kept within the scenario.
  PeerScenarioClient* CreateClient(PeerScenarioClient::Config config);
  PeerScenarioClient* CreateClient(std::string name,
                                   PeerScenarioClient::Config config);

  // Sets up a signaling route that can be used for SDP and ICE.
  SignalingRoute ConnectSignaling(PeerScenarioClient* caller,
                                  PeerScenarioClient* callee,
                                  std::vector<EmulatedNetworkNode*> send_link,
                                  std::vector<EmulatedNetworkNode*> ret_link);

  // Connects two clients over given links. This will also start ICE signaling
  // and SDP negotiation with default behavior. For customized behavior,
  // ConnectSignaling should be used to allow more detailed control, for
  // instance to allow different signaling and media routes.
  void SimpleConnection(PeerScenarioClient* caller,
                        PeerScenarioClient* callee,
                        std::vector<EmulatedNetworkNode*> send_link,
                        std::vector<EmulatedNetworkNode*> ret_link);

  // Starts feeding the results of comparing captured frames from |send_track|
  // with decoded frames on |receiver| to |analyzer|.
  // TODO(srte): Provide a way to detach to allow removal of tracks.
  void AttachVideoQualityAnalyzer(VideoQualityAnalyzer* analyzer,
                                  VideoTrackInterface* send_track,
                                  PeerScenarioClient* receiver);

  // Waits on |event| while processing messages on the signaling thread.
  bool WaitAndProcess(std::atomic<bool>* event,
                      TimeDelta max_duration = TimeDelta::seconds(5));

  // Process messages on the signaling thread for the given duration.
  void ProcessMessages(TimeDelta duration);

 private:
  // Helper struct to maintain ownership of the matcher and taps.
  struct PeerVideoQualityPair {
   public:
    PeerVideoQualityPair(Clock* capture_clock, VideoQualityAnalyzer* analyzer)
        : matcher_({analyzer->Handler()}),
          capture_tap_(capture_clock, &matcher_),
          decode_tap_(capture_clock, &matcher_, 0) {}
    VideoFrameMatcher matcher_;
    CapturedFrameTap capture_tap_;
    DecodedFrameTap decode_tap_;
  };
  Clock* clock() { return Clock::GetRealTimeClock(); }

  std::unique_ptr<LogWriterFactoryInterface> GetLogWriterFactory(
      std::string name);

  rtc::Thread* const signaling_thread_;
  const std::unique_ptr<LogWriterFactoryInterface> log_writer_manager_;
  std::list<PeerVideoQualityPair> video_quality_pairs_;
  NetworkEmulationManagerImpl net_;
  std::list<PeerScenarioClient> peer_clients_;
};

}  // namespace test
}  // namespace webrtc
#endif  // TEST_PEER_SCENARIO_PEER_SCENARIO_H_
