/*
 *  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 RTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_
#define RTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_

#include <array>
#include <cstddef>
#include <memory>
#include <optional>
#include <string>

#include "api/environment/environment.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "p2p/base/basic_packet_socket_factory.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/network/received_packet.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/socket_server.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_tools/network_tester/packet_logger.h"
#include "rtc_tools/network_tester/packet_sender.h"

#ifdef WEBRTC_NETWORK_TESTER_PROTO
#include "rtc_tools/network_tester/network_tester_packet.pb.h"
using webrtc::network_tester::packet::NetworkTesterPacket;
#else
class NetworkTesterPacket;
#endif  // WEBRTC_NETWORK_TESTER_PROTO

namespace webrtc {

constexpr size_t kEthernetMtu = 1500;

class TestController {
 public:
  TestController(const Environment& env,
                 int min_port,
                 int max_port,
                 const std::string& config_file_path,
                 const std::string& log_file_path);
  ~TestController();

  TestController(const TestController&) = delete;
  TestController& operator=(const TestController&) = delete;

  void SendConnectTo(const std::string& hostname, int port);

  void SendData(const NetworkTesterPacket& packet,
                std::optional<size_t> data_size);

  void OnTestDone();

  bool IsTestDone();

 private:
  void OnReadPacket(AsyncPacketSocket* socket,
                    const ReceivedIpPacket& received_packet);
  Environment env_;
  RTC_NO_UNIQUE_ADDRESS SequenceChecker test_controller_thread_checker_;
  std::unique_ptr<SocketServer> socket_server_;
  std::unique_ptr<Thread> packet_sender_thread_;
  BasicPacketSocketFactory socket_factory_
      RTC_GUARDED_BY(packet_sender_thread_);
  const std::string config_file_path_;
  PacketLogger packet_logger_ RTC_GUARDED_BY(packet_sender_thread_);
  Mutex test_done_lock_ RTC_GUARDED_BY(test_controller_thread_checker_);
  bool local_test_done_ RTC_GUARDED_BY(test_done_lock_);
  bool remote_test_done_ RTC_GUARDED_BY(test_done_lock_);
  std::array<char, kEthernetMtu> send_data_
      RTC_GUARDED_BY(packet_sender_thread_);
  std::unique_ptr<AsyncPacketSocket> udp_socket_
      RTC_GUARDED_BY(packet_sender_thread_);
  SocketAddress remote_address_;
  std::unique_ptr<PacketSender> packet_sender_
      RTC_GUARDED_BY(packet_sender_thread_);
  scoped_refptr<PendingTaskSafetyFlag> task_safety_flag_;
};

}  // namespace webrtc

#endif  // RTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_
