// Copyright (c) 2019 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.

#include "quic/quic_transport/quic_transport_client_session.h"

#include <cstdint>
#include <limits>
#include <memory>
#include <string>
#include <utility>

#include "absl/strings/string_view.h"
#include "url/gurl.h"
#include "quic/core/quic_constants.h"
#include "quic/core/quic_crypto_client_stream.h"
#include "quic/core/quic_data_writer.h"
#include "quic/core/quic_error_codes.h"
#include "quic/core/quic_session.h"
#include "quic/core/quic_types.h"
#include "quic/core/quic_versions.h"
#include "quic/platform/api/quic_bug_tracker.h"
#include "quic/platform/api/quic_logging.h"
#include "quic/quic_transport/quic_transport_protocol.h"
#include "quic/quic_transport/quic_transport_stream.h"

namespace quic {

QuicTransportClientSession::QuicTransportClientSession(
    QuicConnection* connection,
    Visitor* owner,
    const QuicConfig& config,
    const ParsedQuicVersionVector& supported_versions,
    const GURL& url,
    QuicCryptoClientConfig* crypto_config,
    url::Origin origin,
    WebTransportVisitor* visitor,
    std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
    : QuicSession(connection,
                  owner,
                  config,
                  supported_versions,
                  /*num_expected_unidirectional_static_streams*/ 0,
                  std::move(datagram_observer)),
      url_(url),
      origin_(origin),
      visitor_(visitor) {
  for (const ParsedQuicVersion& version : supported_versions) {
    QUIC_BUG_IF(quic_bug_12035_1, version.handshake_protocol != PROTOCOL_TLS1_3)
        << "QuicTransport requires TLS 1.3 handshake";
  }
  crypto_stream_ = std::make_unique<QuicCryptoClientStream>(
      QuicServerId(url.host(), url.EffectiveIntPort()), this,
      crypto_config->proof_verifier()->CreateDefaultContext(), crypto_config,
      /*proof_handler=*/this, /*has_application_state = */ true);
}

void QuicTransportClientSession::OnAlpnSelected(absl::string_view alpn) {
  // Defense in-depth: ensure the ALPN selected is the desired one.
  if (alpn != QuicTransportAlpn()) {
    QUIC_BUG(quic_bug_10881_1)
        << "QuicTransport negotiated non-QuicTransport ALPN: " << alpn;
    connection()->CloseConnection(
        QUIC_INTERNAL_ERROR, "QuicTransport negotiated non-QuicTransport ALPN",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return;
  }

  alpn_received_ = true;
}

QuicStream* QuicTransportClientSession::CreateIncomingStream(QuicStreamId id) {
  QUIC_DVLOG(1) << "Creating incoming QuicTransport stream " << id;
  QuicTransportStream* stream = CreateStream(id);
  if (stream->type() == BIDIRECTIONAL) {
    incoming_bidirectional_streams_.push_back(stream);
    visitor_->OnIncomingBidirectionalStreamAvailable();
  } else {
    incoming_unidirectional_streams_.push_back(stream);
    visitor_->OnIncomingUnidirectionalStreamAvailable();
  }
  return stream;
}

void QuicTransportClientSession::SetDefaultEncryptionLevel(
    EncryptionLevel level) {
  QuicSession::SetDefaultEncryptionLevel(level);
  if (level == ENCRYPTION_FORWARD_SECURE) {
    SendClientIndication();
  }
}

void QuicTransportClientSession::OnTlsHandshakeComplete() {
  QuicSession::OnTlsHandshakeComplete();
  SendClientIndication();
}

QuicTransportStream*
QuicTransportClientSession::AcceptIncomingBidirectionalStream() {
  if (incoming_bidirectional_streams_.empty()) {
    return nullptr;
  }
  QuicTransportStream* stream = incoming_bidirectional_streams_.front();
  incoming_bidirectional_streams_.pop_front();
  return stream;
}

QuicTransportStream*
QuicTransportClientSession::AcceptIncomingUnidirectionalStream() {
  if (incoming_unidirectional_streams_.empty()) {
    return nullptr;
  }
  QuicTransportStream* stream = incoming_unidirectional_streams_.front();
  incoming_unidirectional_streams_.pop_front();
  return stream;
}

QuicTransportStream*
QuicTransportClientSession::OpenOutgoingBidirectionalStream() {
  if (!CanOpenNextOutgoingBidirectionalStream()) {
    QUIC_BUG(quic_bug_10881_2)
        << "Attempted to open a stream in violation of flow control";
    return nullptr;
  }
  return CreateStream(GetNextOutgoingBidirectionalStreamId());
}

QuicTransportStream*
QuicTransportClientSession::OpenOutgoingUnidirectionalStream() {
  if (!CanOpenNextOutgoingUnidirectionalStream()) {
    QUIC_BUG(quic_bug_10881_3)
        << "Attempted to open a stream in violation of flow control";
    return nullptr;
  }
  return CreateStream(GetNextOutgoingUnidirectionalStreamId());
}

QuicTransportStream* QuicTransportClientSession::CreateStream(QuicStreamId id) {
  auto stream = std::make_unique<QuicTransportStream>(id, this, this);
  QuicTransportStream* stream_ptr = stream.get();
  ActivateStream(std::move(stream));
  return stream_ptr;
}

std::string QuicTransportClientSession::SerializeClientIndication() {
  std::string serialized_origin = origin_.Serialize();
  if (serialized_origin.size() > std::numeric_limits<uint16_t>::max()) {
    QUIC_BUG(quic_bug_10881_4) << "Client origin too long";
    connection()->CloseConnection(
        QUIC_INTERNAL_ERROR, "Client origin too long",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return "";
  }
  QUIC_DLOG(INFO) << "Sending client indication with origin "
                  << serialized_origin;

  std::string path = url_.PathForRequest();
  if (path.size() > std::numeric_limits<uint16_t>::max()) {
    connection()->CloseConnection(
        QUIC_TRANSPORT_INVALID_CLIENT_INDICATION, "Requested URL path too long",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return "";
  }

  constexpr size_t kPrefixSize =
      sizeof(QuicTransportClientIndicationKeys) + sizeof(uint16_t);
  const size_t buffer_size =
      2 * kPrefixSize + serialized_origin.size() + path.size();
  if (buffer_size > std::numeric_limits<uint16_t>::max()) {
    connection()->CloseConnection(
        QUIC_TRANSPORT_INVALID_CLIENT_INDICATION,
        "Client indication size limit exceeded",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return "";
  }

  std::string buffer;
  buffer.resize(buffer_size);
  QuicDataWriter writer(buffer.size(), &buffer[0]);
  bool success =
      writer.WriteUInt16(
          static_cast<uint16_t>(QuicTransportClientIndicationKeys::kOrigin)) &&
      writer.WriteUInt16(serialized_origin.size()) &&
      writer.WriteStringPiece(serialized_origin) &&
      writer.WriteUInt16(
          static_cast<uint16_t>(QuicTransportClientIndicationKeys::kPath)) &&
      writer.WriteUInt16(path.size()) && writer.WriteStringPiece(path);
  QUIC_BUG_IF(quic_bug_10881_5, !success)
      << "Failed to serialize client indication";
  QUIC_BUG_IF(quic_bug_12035_2, writer.length() != buffer.length())
      << "Serialized client indication has length different from expected";
  return buffer;
}

void QuicTransportClientSession::SendClientIndication() {
  if (!crypto_stream_->encryption_established()) {
    QUIC_BUG(quic_bug_10881_6)
        << "Client indication may only be sent once the encryption is "
           "established.";
    connection()->CloseConnection(
        QUIC_INTERNAL_ERROR, "Attempted to send client indication unencrypted",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return;
  }
  if (ready_) {
    QUIC_BUG(quic_bug_10881_7) << "Client indication may only be sent once.";
    connection()->CloseConnection(
        QUIC_INTERNAL_ERROR, "Attempted to send client indication twice",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return;
  }

  auto client_indication_owned = std::make_unique<ClientIndication>(
      /*stream_id=*/GetNextOutgoingUnidirectionalStreamId(), this,
      /*is_static=*/false, WRITE_UNIDIRECTIONAL);
  QUIC_BUG_IF(quic_bug_12035_3,
              client_indication_owned->id() != ClientIndicationStream())
      << "Client indication stream is " << client_indication_owned->id()
      << " instead of expected " << ClientIndicationStream();
  ClientIndication* client_indication = client_indication_owned.get();
  ActivateStream(std::move(client_indication_owned));

  client_indication->WriteOrBufferData(SerializeClientIndication(),
                                       /*fin=*/true, nullptr);
  client_indication_sent_ = true;

  // Defense in depth: never set the ready bit unless ALPN has been confirmed.
  if (!alpn_received_) {
    QUIC_BUG(quic_bug_10881_8)
        << "ALPN confirmation missing after handshake complete";
    connection()->CloseConnection(
        QUIC_INTERNAL_ERROR,
        "ALPN confirmation missing after handshake complete",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    return;
  }

  // Don't set the ready bit if we closed the connection due to any error
  // beforehand.
  if (!connection()->connected()) {
    return;
  }

  ready_ = true;
  visitor_->OnSessionReady(spdy::SpdyHeaderBlock());
}

void QuicTransportClientSession::OnMessageReceived(absl::string_view message) {
  visitor_->OnDatagramReceived(message);
}

void QuicTransportClientSession::OnCanCreateNewOutgoingStream(
    bool unidirectional) {
  if (unidirectional) {
    visitor_->OnCanCreateNewOutgoingUnidirectionalStream();
  } else {
    visitor_->OnCanCreateNewOutgoingBidirectionalStream();
  }
}

void QuicTransportClientSession::OnProofValid(
    const QuicCryptoClientConfig::CachedState& /*cached*/) {}

void QuicTransportClientSession::OnProofVerifyDetailsAvailable(
    const ProofVerifyDetails& /*verify_details*/) {}

}  // namespace quic
