// Copyright 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 "quiche/quic/core/http/quic_send_control_stream.h"

#include <cstdint>
#include <memory>

#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/crypto/quic_random.h"
#include "quiche/quic/core/http/http_constants.h"
#include "quiche/quic/core/http/quic_spdy_session.h"
#include "quiche/quic/core/quic_session.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/common/structured_headers.h"

namespace quic {
namespace {

// See https://httpwg.org/specs/rfc9218.html for Priority Field Value format.
constexpr absl::string_view kUrgencyKey = "u";
constexpr absl::string_view kIncrementalKey = "i";
constexpr int kMinimumUrgency = 0;
constexpr int kMaximumUrgency = 7;
constexpr bool kDefaultIncremental = false;

}  // anonymous namespace

QuicSendControlStream::QuicSendControlStream(QuicStreamId id,
                                             QuicSpdySession* spdy_session,
                                             const SettingsFrame& settings)
    : QuicStream(id, spdy_session, /*is_static = */ true, WRITE_UNIDIRECTIONAL),
      settings_sent_(false),
      settings_(settings),
      spdy_session_(spdy_session) {}

void QuicSendControlStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
  QUIC_BUG(quic_bug_10382_1)
      << "OnStreamReset() called for write unidirectional stream.";
}

bool QuicSendControlStream::OnStopSending(QuicResetStreamError /* code */) {
  stream_delegate()->OnStreamError(
      QUIC_HTTP_CLOSED_CRITICAL_STREAM,
      "STOP_SENDING received for send control stream");
  return false;
}

void QuicSendControlStream::MaybeSendSettingsFrame() {
  if (settings_sent_) {
    return;
  }

  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
  // Send the stream type on so the peer knows about this stream.
  char data[sizeof(kControlStream)];
  QuicDataWriter writer(ABSL_ARRAYSIZE(data), data);
  writer.WriteVarInt62(kControlStream);
  WriteOrBufferData(absl::string_view(writer.data(), writer.length()), false,
                    nullptr);

  SettingsFrame settings = settings_;
  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.4.1
  // specifies that setting identifiers of 0x1f * N + 0x21 are reserved and
  // greasing should be attempted.
  if (!GetQuicFlag(quic_enable_http3_grease_randomness)) {
    settings.values[0x40] = 20;
  } else {
    uint32_t result;
    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
    uint64_t setting_id = 0x1fULL * static_cast<uint64_t>(result) + 0x21ULL;
    QuicRandom::GetInstance()->RandBytes(&result, sizeof(result));
    settings.values[setting_id] = result;
  }

  std::string settings_frame = HttpEncoder::SerializeSettingsFrame(settings);
  QUIC_DVLOG(1) << "Control stream " << id() << " is writing settings frame "
                << settings;
  if (spdy_session_->debug_visitor()) {
    spdy_session_->debug_visitor()->OnSettingsFrameSent(settings);
  }
  WriteOrBufferData(settings_frame, /*fin = */ false, nullptr);
  settings_sent_ = true;

  // https://tools.ietf.org/html/draft-ietf-quic-http-25#section-7.2.9
  // specifies that a reserved frame type has no semantic meaning and should be
  // discarded. A greasing frame is added here.
  WriteOrBufferData(HttpEncoder::SerializeGreasingFrame(), /*fin = */ false,
                    nullptr);
}

void QuicSendControlStream::WritePriorityUpdate(QuicStreamId stream_id,
                                                int urgency, bool incremental) {
  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
  MaybeSendSettingsFrame();

  const std::string priority_field_value =
      SerializePriorityFieldValue(urgency, incremental);
  PriorityUpdateFrame priority_update_frame{stream_id, priority_field_value};
  if (spdy_session_->debug_visitor()) {
    spdy_session_->debug_visitor()->OnPriorityUpdateFrameSent(
        priority_update_frame);
  }

  std::string frame =
      HttpEncoder::SerializePriorityUpdateFrame(priority_update_frame);
  QUIC_DVLOG(1) << "Control Stream " << id() << " is writing "
                << priority_update_frame;
  WriteOrBufferData(frame, false, nullptr);
}

void QuicSendControlStream::SendGoAway(QuicStreamId id) {
  QuicConnection::ScopedPacketFlusher flusher(session()->connection());
  MaybeSendSettingsFrame();

  GoAwayFrame frame;
  frame.id = id;
  if (spdy_session_->debug_visitor()) {
    spdy_session_->debug_visitor()->OnGoAwayFrameSent(id);
  }

  WriteOrBufferData(HttpEncoder::SerializeGoAwayFrame(frame), false, nullptr);
}

std::string QuicSendControlStream::SerializePriorityFieldValue(
    int urgency, bool incremental) {
  quiche::structured_headers::Dictionary dictionary;

  if (urgency != QuicStream::kDefaultUrgency && urgency >= kMinimumUrgency &&
      urgency <= kMaximumUrgency) {
    dictionary[kUrgencyKey] = quiche::structured_headers::ParameterizedMember(
        quiche::structured_headers::Item(static_cast<int64_t>(urgency)), {});
  }

  if (incremental != kDefaultIncremental) {
    dictionary[kIncrementalKey] =
        quiche::structured_headers::ParameterizedMember(
            quiche::structured_headers::Item(incremental), {});
  }

  absl::optional<std::string> priority_field_value =
      quiche::structured_headers::SerializeDictionary(dictionary);
  if (!priority_field_value.has_value()) {
    QUICHE_BUG(priority_field_value_serialization_failed);
    return "";
  }

  return *priority_field_value;
}

}  // namespace quic
