// 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 <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,
                          bool end_of_message) 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
