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

#ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
#define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_

#include <cstdint>
#include <memory>

#include "absl/strings/string_view.h"
#include "quiche/quic/core/io/socket_factory.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/web_transport_interface.h"
#include "quiche/quic/tools/quic_backend_response.h"
#include "quiche/spdy/core/http2_header_block.h"

namespace quic {

// This interface implements the functionality to fetch a response
// from the backend (such as cache, http-proxy etc) to serve
// requests received by a Quic Server
class QuicSimpleServerBackend {
 public:
  // This interface implements the methods
  // called by the QuicSimpleServerBackend implementation
  // to process the request in the backend
  class RequestHandler {
   public:
    virtual ~RequestHandler() {}

    virtual QuicConnectionId connection_id() const = 0;
    virtual QuicStreamId stream_id() const = 0;
    virtual std::string peer_host() const = 0;
    // Called when the response is ready at the backend and can be send back to
    // the QUIC client.
    virtual void OnResponseBackendComplete(
        const QuicBackendResponse* response) = 0;
    // Sends additional non-full-response data (without headers) to the request
    // stream, e.g. for CONNECT data. May only be called after sending an
    // incomplete response (using `QuicBackendResponse::INCOMPLETE_RESPONSE`).
    // Sends the data with the FIN bit to close the stream if `close_stream` is
    // true.
    virtual void SendStreamData(absl::string_view data, bool close_stream) = 0;
    // Abruptly terminates (resets) the request stream with `error`.
    virtual void TerminateStreamWithError(QuicResetStreamError error) = 0;
  };

  struct WebTransportResponse {
    spdy::Http2HeaderBlock response_headers;
    std::unique_ptr<WebTransportVisitor> visitor;
  };

  virtual ~QuicSimpleServerBackend() = default;
  // This method initializes the backend instance to fetch responses
  // from a backend server, in-memory cache etc.
  virtual bool InitializeBackend(const std::string& backend_url) = 0;
  // Returns true if the backend has been successfully initialized
  // and could be used to fetch HTTP requests
  virtual bool IsBackendInitialized() const = 0;
  // Passes the socket factory in use by the QuicServer. Must live as long as
  // incoming requests/data are still sent to the backend, or until cleared by
  // calling with null. Must not be called while backend is handling requests.
  virtual void SetSocketFactory(SocketFactory* /*socket_factory*/) {}
  // Triggers a HTTP request to be sent to the backend server or cache
  // If response is immediately available, the function synchronously calls
  // the `request_handler` with the HTTP response.
  // If the response has to be fetched over the network, the function
  // asynchronously calls `request_handler` with the HTTP response.
  //
  // Not called for requests using the CONNECT method.
  virtual void FetchResponseFromBackend(
      const spdy::Http2HeaderBlock& request_headers,
      const std::string& request_body, RequestHandler* request_handler) = 0;

  // Handles headers for requests using the CONNECT method. Called immediately
  // on receiving the headers, potentially before the request is complete or
  // data is received. Any response (complete or incomplete) should be sent,
  // potentially asynchronously, using `request_handler`.
  //
  // If not overridden by backend, sends an error appropriate for a server that
  // does not handle CONNECT requests.
  virtual void HandleConnectHeaders(
      const spdy::Http2HeaderBlock& /*request_headers*/,
      RequestHandler* request_handler) {
    spdy::Http2HeaderBlock headers;
    headers[":status"] = "405";
    QuicBackendResponse response;
    response.set_headers(std::move(headers));
    request_handler->OnResponseBackendComplete(&response);
  }
  // Handles data for requests using the CONNECT method.  Called repeatedly
  // whenever new data is available. If `data_complete` is true, data was
  // received with the FIN bit, and this is the last call to this method.
  //
  // If not overridden by backend, abruptly terminates the stream.
  virtual void HandleConnectData(absl::string_view /*data*/,
                                 bool /*data_complete*/,
                                 RequestHandler* request_handler) {
    request_handler->TerminateStreamWithError(
        QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECT_ERROR));
  }

  // Clears the state of the backend  instance
  virtual void CloseBackendResponseStream(RequestHandler* request_handler) = 0;

  virtual WebTransportResponse ProcessWebTransportRequest(
      const spdy::Http2HeaderBlock& /*request_headers*/,
      WebTransportSession* /*session*/) {
    WebTransportResponse response;
    response.response_headers[":status"] = "400";
    return response;
  }
  virtual bool SupportsWebTransport() { return false; }
  virtual bool SupportsExtendedConnect() { return true; }
};

}  // namespace quic

#endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_
