// Copyright 2023 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/tools/devious_baton.h"

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

#include "absl/functional/bind_front.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/crypto/quic_random.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/common/wire_serialization.h"
#include "quiche/web_transport/complete_buffer_visitor.h"
#include "quiche/web_transport/web_transport.h"

namespace quic {

namespace {

constexpr QuicByteCount kMaxPaddingSize = 64;
constexpr char kPaddingData[kMaxPaddingSize] = {0};

absl::StatusOr<DeviousBatonValue> Parse(absl::string_view message) {
  quiche::QuicheDataReader reader(message);
  uint64_t padding_size;
  if (!reader.ReadVarInt62(&padding_size)) {
    return absl::InvalidArgumentError("Failed to read the padding size");
  }
  if (!reader.Seek(padding_size)) {
    return absl::InvalidArgumentError("Failed to skip padding");
  }
  DeviousBatonValue value;
  if (!reader.ReadUInt8(&value)) {
    return absl::InvalidArgumentError("Failed to read the baton");
  }
  if (!reader.IsDoneReading()) {
    return absl::InvalidArgumentError("Trailing data after the baton");
  }
  return value;
}

std::string Serialize(DeviousBatonValue value) {
  // Randomize padding size for extra deviousness.
  QuicByteCount padding_size =
      QuicRandom::GetInstance()->InsecureRandUint64() % kMaxPaddingSize;
  absl::string_view padding(kPaddingData, padding_size);

  absl::StatusOr<std::string> result = quiche::SerializeIntoString(
      quiche::WireStringWithLengthPrefix<quiche::WireVarInt62>(padding),
      quiche::WireUint8(value));
  QUICHE_DCHECK(result.ok());
  return *std::move(result);
}

class IncomingBidiBatonVisitor : public webtransport::CompleteBufferVisitor {
 public:
  IncomingBidiBatonVisitor(webtransport::Session& session,
                           webtransport::Stream& stream)
      : CompleteBufferVisitor(
            &stream, absl::bind_front(
                         &IncomingBidiBatonVisitor::OnAllDataReceived, this)),
        session_(&session) {}

 private:
  void OnAllDataReceived(std::string data) {
    absl::StatusOr<DeviousBatonValue> value = Parse(data);
    if (!value.ok()) {
      session_->CloseSession(kDeviousBatonErrorBruh,
                             absl::StrCat("Failed to parse incoming baton: ",
                                          value.status().message()));
      return;
    }
    DeviousBatonValue next_value = 1 + *value;
    if (next_value != 0) {
      SetOutgoingData(Serialize(*value + 1));
    }
  }

  webtransport::Session* session_;
};

}  // namespace

void DeviousBatonSessionVisitor::OnSessionReady() {
  if (!is_server_) {
    return;
  }
  for (int i = 0; i < count_; ++i) {
    webtransport::Stream* stream = session_->OpenOutgoingUnidirectionalStream();
    if (stream == nullptr) {
      session_->CloseSession(
          kDeviousBatonErrorDaYamn,
          "Insufficient flow control when opening initial baton streams");
      return;
    }
    stream->SetVisitor(std::make_unique<webtransport::CompleteBufferVisitor>(
        stream, Serialize(initial_value_)));
    stream->visitor()->OnCanWrite();
  }
}

void DeviousBatonSessionVisitor::OnSessionClosed(
    webtransport::SessionErrorCode error_code,
    const std::string& error_message) {
  QUICHE_LOG(INFO) << "Devious Baton session closed with error " << error_code
                   << " (message: " << error_message << ")";
}

void DeviousBatonSessionVisitor::OnIncomingBidirectionalStreamAvailable() {
  while (true) {
    webtransport::Stream* stream =
        session_->AcceptIncomingBidirectionalStream();
    if (stream == nullptr) {
      return;
    }
    stream->SetVisitor(
        std::make_unique<IncomingBidiBatonVisitor>(*session_, *stream));
    stream->visitor()->OnCanRead();
  }
}

void DeviousBatonSessionVisitor::OnIncomingUnidirectionalStreamAvailable() {
  while (true) {
    webtransport::Stream* stream =
        session_->AcceptIncomingUnidirectionalStream();
    if (stream == nullptr) {
      return;
    }
    stream->SetVisitor(std::make_unique<webtransport::CompleteBufferVisitor>(
        stream, CreateResponseCallback(
                    &DeviousBatonSessionVisitor::SendBidirectionalBaton)));
    stream->visitor()->OnCanRead();
  }
}

void DeviousBatonSessionVisitor::OnDatagramReceived(
    absl::string_view datagram) {
  // TODO(vasilvv): implement datagram behavior.
}

void DeviousBatonSessionVisitor::OnCanCreateNewOutgoingBidirectionalStream() {
  while (!outgoing_bidi_batons_.empty()) {
    webtransport::Stream* stream = session_->OpenOutgoingBidirectionalStream();
    if (stream == nullptr) {
      return;
    }
    stream->SetVisitor(std::make_unique<webtransport::CompleteBufferVisitor>(
        stream, Serialize(outgoing_bidi_batons_.front()),
        CreateResponseCallback(
            &DeviousBatonSessionVisitor::SendUnidirectionalBaton)));
    outgoing_bidi_batons_.pop_front();
    stream->visitor()->OnCanWrite();
  }
}

void DeviousBatonSessionVisitor::OnCanCreateNewOutgoingUnidirectionalStream() {
  while (!outgoing_unidi_batons_.empty()) {
    webtransport::Stream* stream = session_->OpenOutgoingUnidirectionalStream();
    if (stream == nullptr) {
      return;
    }
    stream->SetVisitor(std::make_unique<webtransport::CompleteBufferVisitor>(
        stream, Serialize(outgoing_unidi_batons_.front())));
    outgoing_unidi_batons_.pop_front();
    stream->visitor()->OnCanWrite();
  }
}

quiche::SingleUseCallback<void(std::string)>
DeviousBatonSessionVisitor::CreateResponseCallback(SendFunction send_function) {
  return [this, send_function](std::string data) {
    absl::StatusOr<DeviousBatonValue> value = Parse(data);
    if (!value.ok()) {
      session_->CloseSession(kDeviousBatonErrorBruh,
                             absl::StrCat("Failed to parse incoming baton: ",
                                          value.status().message()));
      return;
    }
    DeviousBatonValue new_value = 1 + *value;
    if (new_value != 0) {
      std::invoke(send_function, this, *value);
    }
  };
}

}  // namespace quic
