// Copyright (c) 2021 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/test_tools/web_transport_resets_backend.h"

#include <memory>

#include "quic/core/web_transport_interface.h"
#include "quic/tools/web_transport_test_visitors.h"
#include "common/quiche_circular_deque.h"

namespace quic {
namespace test {

namespace {

class ResetsVisitor;

class BidirectionalEchoVisitorWithLogging
    : public WebTransportBidirectionalEchoVisitor {
 public:
  BidirectionalEchoVisitorWithLogging(WebTransportStream* stream,
                                      ResetsVisitor* session_visitor)
      : WebTransportBidirectionalEchoVisitor(stream),
        session_visitor_(session_visitor) {}

  void OnResetStreamReceived(WebTransportStreamError error) override;
  void OnStopSendingReceived(WebTransportStreamError error) override;

 private:
  ResetsVisitor* session_visitor_;  // Not owned.
};

class ResetsVisitor : public WebTransportVisitor {
 public:
  ResetsVisitor(WebTransportSession* session) : session_(session) {}

  void OnSessionReady(const spdy::SpdyHeaderBlock& /*headers*/) override {}
  void OnSessionClosed(WebTransportSessionError /*error_code*/,
                       const std::string& /*error_message*/) override {}

  void OnIncomingBidirectionalStreamAvailable() override {
    while (true) {
      WebTransportStream* stream =
          session_->AcceptIncomingBidirectionalStream();
      if (stream == nullptr) {
        return;
      }
      stream->SetVisitor(
          std::make_unique<BidirectionalEchoVisitorWithLogging>(stream, this));
      stream->visitor()->OnCanRead();
    }
  }
  void OnIncomingUnidirectionalStreamAvailable() override {}

  void OnDatagramReceived(absl::string_view /*datagram*/) override {}

  void OnCanCreateNewOutgoingBidirectionalStream() override {}
  void OnCanCreateNewOutgoingUnidirectionalStream() override {
    MaybeSendLogsBack();
  }

  void Log(std::string line) {
    log_.push_back(std::move(line));
    MaybeSendLogsBack();
  }

 private:
  void MaybeSendLogsBack() {
    while (!log_.empty() &&
           session_->CanOpenNextOutgoingUnidirectionalStream()) {
      WebTransportStream* stream = session_->OpenOutgoingUnidirectionalStream();
      stream->SetVisitor(
          std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(
              stream, log_.front()));
      log_.pop_front();
      stream->visitor()->OnCanWrite();
    }
  }

  WebTransportSession* session_;  // Not owned.
  quiche::QuicheCircularDeque<std::string> log_;
};

void BidirectionalEchoVisitorWithLogging::OnResetStreamReceived(
    WebTransportStreamError error) {
  session_visitor_->Log(absl::StrCat("Received reset for stream ",
                                     stream()->GetStreamId(),
                                     " with error code ", error));
  WebTransportBidirectionalEchoVisitor::OnResetStreamReceived(error);
}
void BidirectionalEchoVisitorWithLogging::OnStopSendingReceived(
    WebTransportStreamError error) {
  session_visitor_->Log(absl::StrCat("Received stop sending for stream ",
                                     stream()->GetStreamId(),
                                     " with error code ", error));
  WebTransportBidirectionalEchoVisitor::OnStopSendingReceived(error);
}

}  // namespace

QuicSimpleServerBackend::WebTransportResponse WebTransportResetsBackend(
    const spdy::Http2HeaderBlock& /*request_headers*/,
    WebTransportSession* session) {
  QuicSimpleServerBackend::WebTransportResponse response;
  response.response_headers[":status"] = "200";
  response.visitor = std::make_unique<ResetsVisitor>(session);
  return response;
}

}  // namespace test
}  // namespace quic
