// Copyright (c) 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 <poll.h>
#include <unistd.h>

#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/strings/str_cat.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/moqt/tools/chat_client.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/tools/interactive_cli.h"
#include "quiche/quic/tools/quic_name_lookup.h"
#include "quiche/quic/tools/quic_url.h"
#include "quiche/common/platform/api/quiche_command_line_flags.h"

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    bool, disable_certificate_verification, false,
    "If true, don't verify the server certificate.");

DEFINE_QUICHE_COMMAND_LINE_FLAG(
    std::string, output_file, "",
    "chat messages will stream to a file instead of stdout");

using ::moqt::moq_chat::ChatClient;
using ::moqt::moq_chat::ChatUserInterface;

// Writes messages to a file, when directed from the command line.
class FileOutput : public ChatUserInterface {
 public:
  explicit FileOutput(absl::string_view filename, absl::string_view username)
      : username_(username) {
    output_file_.open(filename);
    output_file_ << "Chat transcript:\n";
    output_file_.flush();
    std::cout << "Fully connected. Messages are in the output file. Exit the "
              << "session by entering /exit\n";
  }

  ~FileOutput() override { output_file_.close(); }

  void Initialize(quic::InteractiveCli::LineCallback callback,
                  quic::QuicEventLoop* event_loop) override {
    callback_ = std::move(callback);
    event_loop_ = event_loop;
  }

  void WriteToOutput(absl::string_view user,
                     absl::string_view message) override {
    if (message.empty()) {
      return;
    }
    output_file_ << user << ": " << message << "\n\n";
    output_file_.flush();
  }

  void IoLoop() override {
    std::string message_to_send;
    QUIC_BUG_IF(quic_bug_moq_chat_user_interface_unitialized,
                event_loop_ == nullptr)
        << "IoLoop called before Initialize";
    while (poll(&poll_settings_, 1, 0) <= 0) {
      event_loop_->RunEventLoopOnce(moqt::moq_chat::kChatEventLoopDuration);
    }
    std::getline(std::cin, message_to_send);
    callback_(message_to_send);
    WriteToOutput(username_, message_to_send);
  }

 private:
  quic::QuicEventLoop* event_loop_;
  quic::InteractiveCli::LineCallback callback_;
  std::ofstream output_file_;
  absl::string_view username_;
  struct pollfd poll_settings_ = {
      0,
      POLLIN,
      POLLIN,
  };
};

// Writes messages to the terminal, without messing up entry of new messages.
class CliOutput : public ChatUserInterface {
 public:
  void Initialize(quic::InteractiveCli::LineCallback callback,
                  quic::QuicEventLoop* event_loop) override {
    cli_ =
        std::make_unique<quic::InteractiveCli>(event_loop, std::move(callback));
    event_loop_ = event_loop;
    cli_->PrintLine("Fully connected. Enter '/exit' to exit the chat.\n");
  }

  void WriteToOutput(absl::string_view user,
                     absl::string_view message) override {
    QUIC_BUG_IF(quic_bug_moq_chat_user_interface_unitialized, cli_ == nullptr)
        << "WriteToOutput called before Initialize";
    cli_->PrintLine(absl::StrCat(user, ": ", message));
  }

  void IoLoop() override {
    QUIC_BUG_IF(quic_bug_moq_chat_user_interface_unitialized,
                event_loop_ == nullptr)
        << "IoLoop called before Initialize";
    event_loop_->RunEventLoopOnce(moqt::moq_chat::kChatEventLoopDuration);
  }

 private:
  quic::QuicEventLoop* event_loop_;
  std::unique_ptr<quic::InteractiveCli> cli_;
};

// A client for MoQT over chat, used for interop testing. See
// https://afrind.github.io/draft-frindell-moq-chat/draft-frindell-moq-chat.html
int main(int argc, char* argv[]) {
  const char* usage =
      "Usage: chat_client [options] <url> <username> <chat-id> <localhost>";
  std::vector<std::string> args =
      quiche::QuicheParseCommandLineFlags(usage, argc, argv);
  if (args.size() != 4) {
    quiche::QuichePrintCommandLineFlagHelp(usage);
    return 1;
  }
  quic::QuicUrl url(args[0], "https");
  quic::QuicServerId server_id(url.host(), url.port());
  std::string path = url.PathParamsQuery();
  const std::string& username = args[1];
  const std::string& chat_id = args[2];
  std::string localhost = args[3];
  std::string output_filename =
      quiche::GetQuicheCommandLineFlag(FLAGS_output_file);
  std::unique_ptr<ChatUserInterface> interface;

  if (!output_filename.empty()) {
    interface = std::make_unique<FileOutput>(output_filename, username);
  } else {  // Use the CLI.
    interface = std::make_unique<CliOutput>();
  }
  ChatClient client(
      server_id,
      quiche::GetQuicheCommandLineFlag(FLAGS_disable_certificate_verification),
      std::move(interface), chat_id, username, localhost);

  if (!client.Connect(path)) {
    return 1;
  }
  if (!client.AnnounceAndSubscribeAnnounces()) {
    return 1;
  }
  client.IoLoop();
  return 0;
}
