// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_QUARTC_QUARTC_ENDPOINT_H_
#define QUICHE_QUIC_QUARTC_QUARTC_ENDPOINT_H_

#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h"
#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_clock.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
#include "net/third_party/quiche/src/quic/quartc/quartc_connection_helper.h"
#include "net/third_party/quiche/src/quic/quartc/quartc_crypto_helpers.h"
#include "net/third_party/quiche/src/quic/quartc/quartc_dispatcher.h"
#include "net/third_party/quiche/src/quic/quartc/quartc_factory.h"

namespace quic {

// Private implementation of QuartcEndpoint.  Enables different implementations
// for client and server endpoints.
class QuartcEndpointImpl {
 public:
  virtual ~QuartcEndpointImpl() = default;

  virtual QuicStringPiece server_crypto_config() const = 0;
};

// Endpoint (client or server) in a peer-to-peer Quartc connection.
class QuartcEndpoint {
 public:
  class Delegate {
   public:
    virtual ~Delegate() = default;

    // Called when an endpoint creates a new session, before any packets are
    // processed or sent.  The callee should perform any additional
    // configuration required, such as setting a session delegate, before
    // returning.  |session| is owned by the endpoint, but remains safe to use
    // until another call to |OnSessionCreated| occurs, at which point previous
    // session is destroyed.
    virtual void OnSessionCreated(QuartcSession* session) = 0;

    // Called if the endpoint fails to establish a session after a call to
    // Connect.  (The most likely cause is a network idle timeout.)
    virtual void OnConnectError(QuicErrorCode error,
                                const std::string& error_details) = 0;
  };

  virtual ~QuartcEndpoint() = default;

  // Connects the endpoint using the given session config.  After |Connect| is
  // called, the endpoint will asynchronously create a session, then call
  // |Delegate::OnSessionCreated|.
  virtual void Connect(QuartcPacketTransport* packet_transport) = 0;
};

// Implementation of QuartcEndpoint which immediately (but asynchronously)
// creates a session by scheduling a QuicAlarm.  Only suitable for use with the
// client perspective.
class QuartcClientEndpoint : public QuartcEndpoint {
 public:
  // |alarm_factory|, |clock|, and |delegate| are owned by the caller and must
  // outlive the endpoint.
  QuartcClientEndpoint(
      QuicAlarmFactory* alarm_factory,
      const QuicClock* clock,
      Delegate* delegate,
      const QuartcSessionConfig& config,
      QuicStringPiece serialized_server_config,
      std::unique_ptr<QuicVersionManager> version_manager = nullptr);

  void Connect(QuartcPacketTransport* packet_transport) override;

 private:
  friend class CreateSessionDelegate;
  class CreateSessionDelegate : public QuicAlarm::Delegate {
   public:
    CreateSessionDelegate(QuartcClientEndpoint* endpoint)
        : endpoint_(endpoint) {}

    void OnAlarm() override { endpoint_->OnCreateSessionAlarm(); }

   private:
    QuartcClientEndpoint* endpoint_;
  };

  // Callback which occurs when |create_session_alarm_| fires.
  void OnCreateSessionAlarm();

  // Implementation of QuicAlarmFactory used by this endpoint.  Unowned.
  QuicAlarmFactory* alarm_factory_;

  // Implementation of QuicClock used by this endpoint.  Unowned.
  const QuicClock* clock_;

  // Delegate which receives callbacks for newly created sessions.
  QuartcEndpoint::Delegate* delegate_;

  // Server config.  If valid, used to perform a 0-RTT connection.
  const std::string serialized_server_config_;

  // Version manager.  May be injected to control version negotiation in tests.
  std::unique_ptr<QuicVersionManager> version_manager_;

  // Alarm for creating sessions asynchronously.  The alarm is set when
  // Connect() is called.  When it fires, the endpoint creates a session and
  // calls the delegate.
  std::unique_ptr<QuicAlarm> create_session_alarm_;

  // QuartcFactory used by this endpoint to create sessions.  This is an
  // implementation detail of the QuartcEndpoint, and will eventually be
  // replaced by a dispatcher (for servers) or version-negotiation agent (for
  // clients).
  std::unique_ptr<QuartcFactory> factory_;

  // Config to be used for new sessions.
  QuartcSessionConfig config_;

  // The currently-active session.  Nullptr until |Connect| and
  // |Delegate::OnSessionCreated| are called.
  std::unique_ptr<QuartcSession> session_;

  QuartcPacketTransport* packet_transport_;
};

// Implementation of QuartcEndpoint which uses a QuartcDispatcher to listen for
// an incoming CHLO and create a session when one arrives.  Only suitable for
// use with the server perspective.
class QuartcServerEndpoint : public QuartcEndpoint,
                             public QuartcDispatcher::Delegate {
 public:
  QuartcServerEndpoint(
      QuicAlarmFactory* alarm_factory,
      const QuicClock* clock,
      QuartcEndpoint::Delegate* delegate,
      const QuartcSessionConfig& config,
      std::unique_ptr<QuicVersionManager> version_manager = nullptr);

  // Implements QuartcEndpoint.
  void Connect(QuartcPacketTransport* packet_transport) override;

  // Implements QuartcDispatcher::Delegate.
  void OnSessionCreated(QuartcSession* session) override;

  // Accessor to retrieve the server crypto config.  May only be called after
  // Connect().
  QuicStringPiece server_crypto_config() const {
    return crypto_config_.serialized_crypto_config;
  }

  const std::vector<ParsedQuicVersion> GetSupportedQuicVersions() const {
    return version_manager_->GetSupportedVersions();
  }

 private:
  // Implementation of QuicAlarmFactory used by this endpoint.  Unowned.
  QuicAlarmFactory* alarm_factory_;

  // Delegate which receives callbacks for newly created sessions.
  QuartcEndpoint::Delegate* delegate_;

  // Config to be used for new sessions.
  QuartcSessionConfig config_;

  // Version manager.  May be injected to control version negotiation in tests.
  std::unique_ptr<QuicVersionManager> version_manager_;

  // QuartcDispatcher waits for an incoming CHLO, then either rejects it or
  // creates a session to respond to it.  The dispatcher owns all sessions it
  // creates.
  std::unique_ptr<QuartcDispatcher> dispatcher_;

  // This field is only available before connection was started.
  std::unique_ptr<QuartcConnectionHelper> pre_connection_helper_;

  // A configuration, containing public key, that may need to be passed to the
  // client to enable 0rtt.
  CryptoServerConfig crypto_config_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_QUARTC_QUARTC_ENDPOINT_H_
