/*
 *  Copyright 2004 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_BASE_STUN_REQUEST_H_
#define P2P_BASE_STUN_REQUEST_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <span>
#include <string>

#include "api/environment/environment.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "api/task_queue/task_queue_base.h"
#include "api/transport/stun.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

class StunRequest;

const int kAllRequestsForTest = 0;

// Total max timeouts: 39.75 seconds
// For years, this was 9.5 seconds, but for networks that experience moments of
// high RTT (such as 40s on 2G networks), this doesn't work well.
const int STUN_TOTAL_TIMEOUT = 39750;  // milliseconds

// Manages a set of STUN requests, sending and resending until we receive a
// response or determine that the request has timed out.
class StunRequestManager {
 public:
  StunRequestManager(
      TaskQueueBase* thread,
      std::function<void(std::span<const uint8_t>, StunRequest*)> send_packet);
  ~StunRequestManager();

  // Starts sending the given request (perhaps after a delay).
  void Send(std::unique_ptr<StunRequest> request,
            TimeDelta delay = TimeDelta::Zero());

  // If `msg_type` is kAllRequestsForTest, sends all pending requests right
  // away. Otherwise, sends those that have a matching type right away. Only for
  // testing.
  // TODO(tommi): Remove this method and update tests that use it to simulate
  // production code.
  void FlushForTest(int msg_type);

  // Returns true if at least one request with `msg_type` is scheduled for
  // transmission. For testing only.
  // TODO(tommi): Remove this method and update tests that use it to simulate
  // production code.
  bool HasRequestForTest(int msg_type);

  // Removes all stun requests that were added previously.
  void Clear();

  // Determines whether the given message is a response to one of the
  // outstanding requests, and if so, processes it appropriately.
  bool CheckResponse(StunMessage* msg);
  bool CheckResponse(std::span<const uint8_t> payload);

  // Called from a StunRequest when a timeout occurs.
  void OnRequestTimedOut(StunRequest* request);

  bool empty() const;

  TaskQueueBase* network_thread() const { return thread_; }

  void SendPacket(std::span<const uint8_t> data, StunRequest* request);

 private:
  typedef std::map<std::string, std::unique_ptr<StunRequest>, std::less<>>
      RequestMap;

  TaskQueueBase* const thread_;
  RequestMap requests_ RTC_GUARDED_BY(thread_);
  const std::function<void(std::span<const uint8_t>, StunRequest*)>
      send_packet_;
};

// Represents an individual request to be sent.  The STUN message can either be
// constructed beforehand or built on demand.
class StunRequest {
 public:
  StunRequest(const Environment& env, StunRequestManager& manager);
  StunRequest(const Environment& env,
              StunRequestManager& manager,
              std::unique_ptr<StunMessage> message);
  virtual ~StunRequest();

  // The manager handling this request (if it has been scheduled for sending).
  StunRequestManager* manager() { return &manager_; }

  // Returns the transaction ID of this request.
  const std::string& id() const { return msg_->transaction_id(); }

  // Returns the reduced transaction ID of this request.
  uint32_t reduced_transaction_id() const {
    return msg_->reduced_transaction_id();
  }

  // Returns the STUN type of the request message.
  int type();

  // Returns a const pointer to `msg_`.
  const StunMessage* msg() const;

  // Time elapsed since last send.
  TimeDelta Elapsed() const;

  // Add method to explitly allow requests w/o password.
  // - STUN_BINDINGs from StunPort to a stun server
  // - The initial TURN_ALLOCATE_REQUEST
  void SetAuthenticationRequired(bool val) { authentication_required_ = val; }
  bool AuthenticationRequired() const { return authentication_required_; }

 protected:
  friend class StunRequestManager;

  const Environment& env() { return env_; }

  // Called by StunRequestManager.
  void Send(TimeDelta delay);

  // Called from FlushForTest.
  // TODO(tommi): Remove when FlushForTest gets removed.
  void ResetTasksForTest();

  StunMessage* mutable_msg() { return msg_.get(); }

  // Called when the message receives a response or times out.
  virtual void OnResponse(StunMessage* /* response */) {}
  virtual void OnErrorResponse(StunMessage* /* response */) {}
  virtual void OnTimeout() {}
  // Called when the message is sent.
  virtual void OnSent();
  // Returns the next delay for resends in milliseconds.
  virtual int resend_delay();

  TaskQueueBase* network_thread() const { return manager_.network_thread(); }

  void set_timed_out();

 private:
  void SendInternal();
  // Calls `PostDelayedTask` to queue up a call to SendInternal after the
  // specified timeout.
  void SendDelayed(TimeDelta delay);

  const Environment env_;
  StunRequestManager& manager_;
  const std::unique_ptr<StunMessage> msg_;
  Timestamp tstamp_ RTC_GUARDED_BY(network_thread());
  int count_ RTC_GUARDED_BY(network_thread());
  bool timeout_ RTC_GUARDED_BY(network_thread());
  ScopedTaskSafety task_safety_{
      PendingTaskSafetyFlag::CreateDetachedInactive()};
  bool authentication_required_ = true;
};

}  //  namespace webrtc


#endif  // P2P_BASE_STUN_REQUEST_H_
