// Copyright (c) 2024 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_MOQT_TOOLS_CHAT_CLIENT_H
#define QUICHE_QUIC_MOQT_TOOLS_CHAT_CLIENT_H

#include <cstdint>
#include <memory>
#include <optional>
#include <variant>

#include "absl/base/nullability.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/core/quic_server_id.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/moqt/moqt_error.h"
#include "quiche/quic/moqt/moqt_fetch_task.h"
#include "quiche/quic/moqt/moqt_key_value_pair.h"
#include "quiche/quic/moqt/moqt_known_track_publisher.h"
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/moqt/moqt_names.h"
#include "quiche/quic/moqt/moqt_object.h"
#include "quiche/quic/moqt/moqt_outgoing_queue.h"
#include "quiche/quic/moqt/moqt_session.h"
#include "quiche/quic/moqt/moqt_session_callbacks.h"
#include "quiche/quic/moqt/moqt_session_interface.h"
#include "quiche/quic/moqt/tools/moqt_client.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_callbacks.h"

namespace moqt::moq_chat {

constexpr quic::QuicTime::Delta kChatEventLoopDuration =
    quic::QuicTime::Delta::FromMilliseconds(500);

// Chat clients accept a ChatUserInterface that implements how user input is
// captured, and peer messages are displayed.
class ChatUserInterface {
 public:
  virtual ~ChatUserInterface() = default;

  // ChatUserInterface cannot be used until initialized. This is separate from
  // the constructor, because the constructor might create the event loop.
  // |callback| is what ChatUserInterface will call when there is user input.
  // |event_loop| is the event loop that the ChatUserInterface should use.
  virtual void Initialize(
      quiche::MultiUseCallback<void(absl::string_view)> callback,
      quic::QuicEventLoop* event_loop) = 0;
  // Write a peer message to the user output.
  virtual void WriteToOutput(absl::string_view user,
                             absl::string_view message) = 0;
  // Run the event loop for a short interval and exit.
  virtual void IoLoop() = 0;
};

class ChatClient {
 public:
  // If |event_loop| is nullptr, a new one will be created. If multiple
  // endpoints are running on the same thread, as in tests, they should share
  // an event loop.
  ChatClient(const quic::QuicServerId& server_id, bool ignore_certificate,
             std::unique_ptr<ChatUserInterface> interface,
             absl::string_view chat_id, absl::string_view username,
             absl::string_view localhost,
             quic::QuicEventLoop* event_loop = nullptr);
  ~ChatClient() {
    if (!session_is_open_) {
      return;
    }
    session_is_open_ = false;
    if (session_ != nullptr) {
      // Closing the session can trigger a number of callbacks. The application
      // is tearing down too, so negate them.r;
      session_->Close();
      session_ = nullptr;
    }
  }

  // Establish the MoQT session. Returns false if it fails.
  bool Connect(absl::string_view path);

  void OnTerminalLineInput(absl::string_view input_message);

  // Run the event loop until an input or output event is ready, or the
  // session closes.
  void IoLoop() {
    while (session_is_open_) {
      interface_->IoLoop();
    }
  }

  void WriteToOutput(absl::string_view user, absl::string_view message) {
    if (interface_ != nullptr) {
      interface_->WriteToOutput(user, message);
    }
  }

  quic::QuicEventLoop* event_loop() { return event_loop_; }

  class QUICHE_EXPORT RemoteTrackVisitor : public moqt::SubscribeVisitor {
   public:
    RemoteTrackVisitor(ChatClient* client) : client_(client) {}

    void OnReply(
        const moqt::FullTrackName& full_track_name,
        std::variant<SubscribeOkData, MoqtRequestErrorInfo> response) override;

    void OnCanAckObjects(MoqtObjectAckFunction) override {}

    void OnObjectFragment(const moqt::FullTrackName& full_track_name,
                          const PublishedObjectMetadata& metadata,
                          absl::string_view object, uint64_t offset) override;

    void OnPublishDone(FullTrackName) override {}

    // TODO(martinduke): Implement this.
    void OnMalformedTrack(const FullTrackName& /*full_track_name*/) override {}

    void OnStreamFin(const FullTrackName&, DataStreamIndex) override {}
    void OnStreamReset(const FullTrackName&, DataStreamIndex) override {}

   private:
    ChatClient* client_;
  };

  // Returns false on error.
  bool PublishNamespaceAndSubscribeNamespace();

  bool session_is_open() const { return session_is_open_; }

  // Returns true if the client has outstanding subscribes.
  bool is_syncing() const { return subscribes_to_make_ > 0; }

 private:
  void RunEventLoop() { event_loop_->RunEventLoopOnce(kChatEventLoopDuration); }
  // Callback for incoming publish_namespaces. If |parameters| is not nullopt,
  // it's a PUBLISH_NAMESPACE or NAMESPACE. If |callback| is not nullptr, it's
  // a PUBLISH_NAMESPACE.
  void OnIncomingPublishNamespace(
      const moqt::TrackNamespace& track_namespace,
      const std::optional<MessageParameters>& parameters,
      moqt::MoqtResponseCallback absl_nullable callback);

  // Basic session information
  FullTrackName my_track_name_;

  // Related to subscriptions/publish_namespaces
  // TODO: One for each subscribe
  RemoteTrackVisitor remote_track_visitor_;

  // General state variables
  // The event loop to use for this client.
  quic::QuicEventLoop* event_loop_;
  // If the client created its own event loop, it will own it.
  std::unique_ptr<quic::QuicEventLoop> local_event_loop_;
  bool connect_failed_ = false;
  bool session_is_open_ = false;
  moqt::MoqtSession* session_ = nullptr;
  moqt::MoqtKnownTrackPublisher publisher_;
  std::unique_ptr<moqt::MoqtClient> client_;
  moqt::MoqtSessionCallbacks session_callbacks_;
  std::unique_ptr<moqt::MoqtNamespaceTask> namespace_task_;

  // Related to syncing.
  absl::flat_hash_set<FullTrackName> other_users_;
  int subscribes_to_make_ = 0;

  // Handling outgoing messages
  std::shared_ptr<moqt::MoqtOutgoingQueue> queue_;

  // User interface for input and output.
  std::unique_ptr<ChatUserInterface> interface_;
};

}  // namespace moqt::moq_chat

#endif  // QUICHE_QUIC_MOQT_TOOLS_CHAT_CLIENT_H
