/*
 *  Copyright 2010 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 P2P_TEST_FAKE_PORT_ALLOCATOR_H_
#define P2P_TEST_FAKE_PORT_ALLOCATOR_H_

#include <cstdint>
#include <memory>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/functional/any_invocable.h"
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "api/candidate.h"
#include "api/environment/environment.h"
#include "api/packet_socket_factory.h"
#include "api/task_queue/task_queue_base.h"
#include "p2p/base/basic_packet_socket_factory.h"
#include "p2p/base/port.h"
#include "p2p/base/port_allocator.h"
#include "p2p/base/port_interface.h"
#include "p2p/base/stun_port.h"
#include "rtc_base/async_packet_socket.h"
#include "rtc_base/checks.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/net_helpers.h"
#include "rtc_base/net_test_helpers.h"
#include "rtc_base/network.h"
#include "rtc_base/socket_factory.h"
#include "rtc_base/task_queue_for_test.h"
#include "rtc_base/weak_ptr.h"

namespace webrtc {

class TestUDPPort : public UDPPort {
 public:
  static TestUDPPort* Create(const PortParametersRef& args,
                             uint16_t min_port,
                             uint16_t max_port,
                             bool emit_localhost_for_anyaddress) {
    TestUDPPort* port = new TestUDPPort(args, min_port, max_port,
                                        emit_localhost_for_anyaddress);
    if (!port->Init()) {
      delete port;
      port = nullptr;
    }
    return port;
  }

  static std::unique_ptr<TestUDPPort> Create(
      const PortParametersRef& args,
      AsyncPacketSocket* socket,
      bool emit_localhost_for_anyaddress) {
    auto port = absl::WrapUnique(
        new TestUDPPort(args, socket, emit_localhost_for_anyaddress));
    if (!port->Init()) {
      return nullptr;
    }
    return port;
  }

 protected:
  TestUDPPort(const PortParametersRef& args,
              uint16_t min_port,
              uint16_t max_port,
              bool emit_localhost_for_anyaddress)
      : UDPPort(args,
                IceCandidateType::kHost,
                min_port,
                max_port,
                emit_localhost_for_anyaddress) {}

  TestUDPPort(const PortParametersRef& args,
              AsyncPacketSocket* socket,
              bool emit_localhost_for_anyaddress)
      : UDPPort(args,
                IceCandidateType::kHost,
                socket,
                emit_localhost_for_anyaddress) {}
};

// A FakePortAllocatorSession can be used with either a real or fake socket
// factory. It gathers a single loopback port, using IPv6 if available and
// not disabled.
class FakePortAllocatorSession : public PortAllocatorSession {
 public:
  FakePortAllocatorSession(const Environment& env,
                           PortAllocator* allocator,
                           TaskQueueBase* network_thread,
                           PacketSocketFactory* factory,
                           absl::string_view content_name,
                           int component,
                           absl::string_view ice_ufrag,
                           absl::string_view ice_pwd)
      : PortAllocatorSession(content_name,
                             component,
                             ice_ufrag,
                             ice_pwd,
                             allocator->flags()),
        env_(env),
        allocator_(allocator),
        network_thread_(network_thread),
        factory_(factory),
        ipv4_network_("network", "unittest", GetLoopbackIP(AF_INET), 32),
        ipv6_network_("network", "unittest", GetLoopbackIP(AF_INET6), 64),
        port_(),
        port_config_count_(0),
        stun_servers_(allocator->stun_servers()),
        turn_servers_(allocator->turn_servers()) {
    ipv4_network_.AddIP(GetLoopbackIP(AF_INET));
    ipv6_network_.AddIP(GetLoopbackIP(AF_INET6));
  }

  void SetCandidateFilter(uint32_t filter) override {
    candidate_filter_ = filter;
  }

  void StartGettingPorts() override {
    if (!port_) {
      Network& network =
          (HasIPv6Enabled() && (flags() & PORTALLOCATOR_ENABLE_IPV6))
              ? ipv6_network_
              : ipv4_network_;
      port_.reset(
          TestUDPPort::Create({.env = env_,
                               .network_thread = network_thread_,
                               .socket_factory = factory_,
                               .network = &network,
                               .ice_username_fragment = username(),
                               .ice_password = password(),
                               .ice_tiebreaker = allocator_->ice_tiebreaker()},
                              0, 0, false));
      RTC_DCHECK(port_);
      port_->SubscribePortDestroyed(
          this, [this](PortInterface* port) { OnPortDestroyed(port); });
      AddPort(port_.get());
    }
    ++port_config_count_;
    running_ = true;
  }

  void StopGettingPorts() override { running_ = false; }
  bool IsGettingPorts() override { return running_; }
  void ClearGettingPorts() override { is_cleared = true; }
  bool IsCleared() const override { return is_cleared; }

  void RegatherOnFailedNetworks() override {
    NotifyIceRegathering(this, IceRegatheringReason::NETWORK_FAILURE);
  }

  std::vector<PortInterface*> ReadyPorts() const override {
    return ready_ports_;
  }
  std::vector<Candidate> ReadyCandidates() const override {
    return candidates_;
  }
  void PruneAllPorts() override { port_->Prune(); }
  bool CandidatesAllocationDone() const override { return allocation_done_; }

  int port_config_count() { return port_config_count_; }

  const ServerAddresses& stun_servers() const { return stun_servers_; }

  const std::vector<RelayServerConfig>& turn_servers() const {
    return turn_servers_;
  }

  uint32_t candidate_filter() const { return candidate_filter_; }

  int transport_info_update_count() const {
    return transport_info_update_count_;
  }

 protected:
  void UpdateIceParametersInternal() override {
    // Since this class is a fake and this method only is overridden for tests,
    // we don't need to actually update the transport info.
    ++transport_info_update_count_;
  }

 private:
  void AddPort(Port* port) {
    port->set_component(component());
    port->set_generation(generation());
    port->SubscribePortComplete(this,
                                [this](Port* port) { OnPortComplete(port); });
    port->PrepareAddress();
    ready_ports_.push_back(port);
    NotifyPortReady(this, port);
    port->KeepAliveUntilPruned();
  }
  void OnPortComplete(Port* port) {
    const std::vector<Candidate>& candidates = port->Candidates();
    candidates_.insert(candidates_.end(), candidates.begin(), candidates.end());
    NotifyCandidatesReady(this, candidates);

    allocation_done_ = true;
    NotifyCandidatesAllocationDone(this);
  }
  void OnPortDestroyed(PortInterface* /* port */) {
    // Don't want to double-delete port if it deletes itself.
    port_.release();
  }

  const Environment env_;
  PortAllocator* allocator_;
  TaskQueueBase* network_thread_;
  PacketSocketFactory* factory_;
  Network ipv4_network_;
  Network ipv6_network_;
  std::unique_ptr<Port> port_;
  int port_config_count_;
  std::vector<Candidate> candidates_;
  std::vector<PortInterface*> ready_ports_;
  bool allocation_done_ = false;
  bool is_cleared = false;
  ServerAddresses stun_servers_;
  std::vector<RelayServerConfig> turn_servers_;
  uint32_t candidate_filter_ = CF_ALL;
  int transport_info_update_count_ = 0;
  bool running_ = false;
};

class FakePortAllocator : public PortAllocator {
 public:
  FakePortAllocator(
      const Environment& env,
      SocketFactory* absl_nonnull socket_factory,
      TaskQueueBase* absl_nonnull network_thread = TaskQueueBase::Current())
      : env_(env), network_thread_(network_thread), factory_(socket_factory) {
    RTC_CHECK(network_thread);
    SendTask(network_thread_, [this] { Initialize(); });
  }

  void SetNetworkIgnoreMask(int /* network_ignore_mask */) override {}

  PortAllocatorSession* CreateSessionInternal(
      absl::string_view content_name,
      int component,
      absl::string_view ice_ufrag,
      absl::string_view ice_pwd) override {
    return new FakePortAllocatorSession(env_, this, network_thread_, &factory_,
                                        content_name, component, ice_ufrag,
                                        ice_pwd);
  }

  bool initialized() const { return initialized_; }

  // For testing: Manipulate MdnsObfuscationEnabled()
  bool MdnsObfuscationEnabled() const override {
    return mdns_obfuscation_enabled_;
  }

  void SetMdnsObfuscationEnabledForTesting(bool enabled) {
    mdns_obfuscation_enabled_ = enabled;
  }

  void DiscardCandidatePool() override {
    PortAllocator::DiscardCandidatePool();
    if (on_candidate_pool_discarded_) {
      on_candidate_pool_discarded_();
    }
  }

  void SetOnDiscardCandidatePool(
      absl::AnyInvocable<void()> on_candidate_pool_discarded) {
    on_candidate_pool_discarded_ = std::move(on_candidate_pool_discarded);
  }

  WeakPtr<FakePortAllocator> NewWeakPtr() { return weak_factory_.GetWeakPtr(); }

 private:
  const Environment env_;
  TaskQueueBase* absl_nonnull network_thread_;
  BasicPacketSocketFactory factory_;
  bool mdns_obfuscation_enabled_ = false;
  absl::AnyInvocable<void()> on_candidate_pool_discarded_;
  WeakPtrFactory<FakePortAllocator> weak_factory_{this};
};

}  //  namespace webrtc


#endif  // P2P_TEST_FAKE_PORT_ALLOCATOR_H_
