// 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 "quiche/quic/tools/quic_transport_simple_server_session.h"

#include <memory>

#include "url/gurl.h"
#include "url/origin.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/quic_transport/quic_transport_protocol.h"
#include "quiche/quic/quic_transport/quic_transport_stream.h"
#include "quiche/quic/tools/web_transport_test_visitors.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/platform/api/quiche_mem_slice.h"
#include "quiche/common/quiche_buffer_allocator.h"

namespace quic {

QuicTransportSimpleServerSession::QuicTransportSimpleServerSession(
    QuicConnection* connection, bool owns_connection, Visitor* owner,
    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
    const QuicCryptoServerConfig* crypto_config,
    QuicCompressedCertsCache* compressed_certs_cache,
    std::vector<url::Origin> accepted_origins)
    : QuicTransportServerSession(connection, owner, config, supported_versions,
                                 crypto_config, compressed_certs_cache, this),
      owns_connection_(owns_connection),
      mode_(DISCARD),
      accepted_origins_(accepted_origins) {}

QuicTransportSimpleServerSession::~QuicTransportSimpleServerSession() {
  if (owns_connection_) {
    DeleteConnection();
  }
}

void QuicTransportSimpleServerSession::OnIncomingDataStream(
    QuicTransportStream* stream) {
  switch (mode_) {
    case DISCARD:
      stream->SetVisitor(std::make_unique<WebTransportDiscardVisitor>(stream));
      break;

    case ECHO:
      switch (stream->type()) {
        case BIDIRECTIONAL:
          QUIC_DVLOG(1) << "Opening bidirectional echo stream " << stream->id();
          stream->SetVisitor(
              std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
          break;
        case READ_UNIDIRECTIONAL:
          QUIC_DVLOG(1)
              << "Started receiving data on unidirectional echo stream "
              << stream->id();
          stream->SetVisitor(
              std::make_unique<WebTransportUnidirectionalEchoReadVisitor>(
                  stream,
                  [this](const std::string& s) { this->EchoStreamBack(s); }));
          break;
        default:
          QUICHE_NOTREACHED();
          break;
      }
      break;

    case OUTGOING_BIDIRECTIONAL:
      stream->SetVisitor(std::make_unique<WebTransportDiscardVisitor>(stream));
      ++pending_outgoing_bidirectional_streams_;
      MaybeCreateOutgoingBidirectionalStream();
      break;
  }
}

void QuicTransportSimpleServerSession::OnCanCreateNewOutgoingStream(
    bool unidirectional) {
  if (mode_ == ECHO && unidirectional) {
    MaybeEchoStreamsBack();
  } else if (mode_ == OUTGOING_BIDIRECTIONAL && !unidirectional) {
    MaybeCreateOutgoingBidirectionalStream();
  }
}

bool QuicTransportSimpleServerSession::CheckOrigin(url::Origin origin) {
  if (accepted_origins_.empty()) {
    return true;
  }

  for (const url::Origin& accepted_origin : accepted_origins_) {
    if (origin.IsSameOriginWith(accepted_origin)) {
      return true;
    }
  }
  return false;
}

bool QuicTransportSimpleServerSession::ProcessPath(const GURL& url) {
  if (url.path() == "/discard") {
    mode_ = DISCARD;
    return true;
  }
  if (url.path() == "/echo") {
    mode_ = ECHO;
    return true;
  }
  if (url.path() == "/receive-bidirectional") {
    mode_ = OUTGOING_BIDIRECTIONAL;
    return true;
  }

  QUIC_DLOG(WARNING) << "Unknown path requested: " << url.path();
  return false;
}

void QuicTransportSimpleServerSession::OnMessageReceived(
    absl::string_view message) {
  if (mode_ != ECHO) {
    return;
  }
  datagram_queue()->SendOrQueueDatagram(
      quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
          connection()->helper()->GetStreamSendBufferAllocator(), message)));
}

void QuicTransportSimpleServerSession::MaybeEchoStreamsBack() {
  while (!streams_to_echo_back_.empty() &&
         CanOpenNextOutgoingUnidirectionalStream()) {
    // Remove the stream from the queue first, in order to avoid accidentally
    // entering an infinite loop in case any of the following code calls
    // OnCanCreateNewOutgoingStream().
    std::string data = std::move(streams_to_echo_back_.front());
    streams_to_echo_back_.pop_front();

    auto stream_owned = std::make_unique<QuicTransportStream>(
        GetNextOutgoingUnidirectionalStreamId(), this, this);
    QuicTransportStream* stream = stream_owned.get();
    ActivateStream(std::move(stream_owned));
    QUIC_DVLOG(1) << "Opened echo response stream " << stream->id();

    stream->SetVisitor(
        std::make_unique<WebTransportUnidirectionalEchoWriteVisitor>(stream,
                                                                     data));
    stream->visitor()->OnCanWrite();
  }
}

void QuicTransportSimpleServerSession::
    MaybeCreateOutgoingBidirectionalStream() {
  while (pending_outgoing_bidirectional_streams_ > 0 &&
         CanOpenNextOutgoingBidirectionalStream()) {
    auto stream_owned = std::make_unique<QuicTransportStream>(
        GetNextOutgoingBidirectionalStreamId(), this, this);
    QuicTransportStream* stream = stream_owned.get();
    ActivateStream(std::move(stream_owned));
    QUIC_DVLOG(1) << "Opened outgoing bidirectional stream " << stream->id();
    stream->SetVisitor(
        std::make_unique<WebTransportBidirectionalEchoVisitor>(stream));
    if (!stream->Write("hello")) {
      QUIC_DVLOG(1) << "Write failed.";
    }
    --pending_outgoing_bidirectional_streams_;
  }
}

}  // namespace quic
