// 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/moqt/tools/moqt_client.h"

#include <memory>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/quic/core/crypto/proof_verifier.h"
#include "quiche/quic/core/http/quic_spdy_client_stream.h"
#include "quiche/quic/core/http/web_transport_http3.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/core/quic_server_id.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/moqt/moqt_quic_config.h"
#include "quiche/quic/moqt/moqt_session.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/tools/quic_default_client.h"
#include "quiche/quic/tools/quic_event_loop_tools.h"
#include "quiche/quic/tools/quic_name_lookup.h"
#include "quiche/common/http/http_header_block.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/web_transport/web_transport_headers.h"

namespace moqt {

MoqtClient::MoqtClient(quic::QuicSocketAddress peer_address,
                       const quic::QuicServerId& server_id,
                       std::unique_ptr<quic::ProofVerifier> proof_verifier,
                       quic::QuicEventLoop* event_loop)
    : spdy_client_(peer_address, server_id, GetMoqtSupportedQuicVersions(),
                   event_loop, std::move(proof_verifier)) {
  TuneQuicConfig(*spdy_client_.config());
  spdy_client_.set_enable_web_transport(true);
}

void MoqtClient::Connect(std::string path, MoqtSessionCallbacks callbacks) {
  absl::Status status = ConnectInner(std::move(path), callbacks);
  if (!status.ok()) {
    std::move(callbacks.session_terminated_callback)(status.message());
  }
}

absl::Status MoqtClient::ConnectInner(std::string path,
                                      MoqtSessionCallbacks& callbacks) {
  if (!spdy_client_.Initialize()) {
    return absl::InternalError("Initialization failed");
  }
  if (!spdy_client_.Connect()) {
    return absl::UnavailableError("Failed to establish a QUIC connection");
  }
  bool settings_received = quic::ProcessEventsUntil(
      spdy_client_.default_network_helper()->event_loop(),
      [&] { return spdy_client_.client_session()->settings_received(); });
  if (!settings_received) {
    return absl::UnavailableError(
        "Timed out while waiting for server SETTINGS");
  }
  if (!spdy_client_.client_session()->SupportsWebTransport()) {
    QUICHE_DLOG(INFO) << "session: SupportsWebTransport = "
                      << spdy_client_.client_session()->SupportsWebTransport()
                      << ", SupportsH3Datagram = "
                      << spdy_client_.client_session()->SupportsH3Datagram()
                      << ", OneRttKeysAvailable = "
                      << spdy_client_.client_session()->OneRttKeysAvailable();
    return absl::FailedPreconditionError(
        "Server does not support WebTransport");
  }
  auto* stream = static_cast<quic::QuicSpdyClientStream*>(
      spdy_client_.client_session()->CreateOutgoingBidirectionalStream());
  if (!stream) {
    return absl::InternalError("Could not open a CONNECT stream");
  }
  spdy_client_.set_store_response(true);

  quiche::HttpHeaderBlock headers;
  headers[":scheme"] = "https";
  headers[":authority"] = spdy_client_.server_id().host();
  headers[":path"] = path;
  headers[":method"] = "CONNECT";
  headers[":protocol"] = "webtransport";
  std::string version = std::string(kDefaultMoqtVersion);
  absl::StatusOr<std::string> serialized_version =
      webtransport::SerializeSubprotocolRequestHeader(
          absl::MakeSpan(&version, 1));
  if (!serialized_version.ok()) {
    return serialized_version.status();
  }
  headers["wt-available-protocols"] = *serialized_version;
  stream->SendRequest(std::move(headers), "", false);

  quic::WebTransportHttp3* web_transport = stream->web_transport();
  if (web_transport == nullptr) {
    return absl::InternalError("Failed to initialize WebTransport session");
  }

  MoqtSessionParameters parameters(quic::Perspective::IS_CLIENT);

  // Ensure that we never have a dangling pointer to the session.
  MoqtSessionDeletedCallback deleted_callback =
      std::move(callbacks.session_deleted_callback);
  callbacks.session_deleted_callback =
      [this, old = std::move(deleted_callback)]() mutable {
        session_ = nullptr;
        std::move(old)();
      };

  auto session = std::make_unique<MoqtSession>(
      web_transport, parameters,
      spdy_client_.default_network_helper()->event_loop()->CreateAlarmFactory(),
      std::move(callbacks));
  session_ = session.get();
  web_transport->SetVisitor(std::move(session));
  return absl::OkStatus();
}

}  // namespace moqt
