// Copyright 2019 The Fuchsia 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 SRC_BRINGUP_BIN_PTYSVC_PTY_SERVER_H_
#define SRC_BRINGUP_BIN_PTYSVC_PTY_SERVER_H_

#include <fidl/fuchsia.device/cpp/wire.h>
#include <fidl/fuchsia.hardware.pty/cpp/wire.h>
#include <lib/zx/eventpair.h>

#include "fifo.h"

// forward-decl
class PtyClient;

class PtyServer : public std::enable_shared_from_this<PtyServer>,
                  public fidl::WireServer<fuchsia_hardware_pty::Device> {
 public:
  class Args {
   public:
    static zx::result<Args> Create();

   private:
    friend class PtyServer;

    zx::eventpair local_, remote_;
  };

  PtyServer(Args args, async_dispatcher_t* dispatcher);
  ~PtyServer() override;

  async_dispatcher_t* dispatcher() { return dispatcher_; }

  zx_status_t Read(void* data, size_t count, size_t* out_actual);
  zx_status_t Write(const void* data, size_t count, size_t* out_actual);

  void AddConnection(fidl::ServerEnd<fuchsia_hardware_pty::Device> request);

  void Clone2(Clone2RequestView request, Clone2Completer::Sync& completer) final;
  void Close(CloseCompleter::Sync& completer) final;
  void Query(QueryCompleter::Sync& completer) final;
  void Read(ReadRequestView request, ReadCompleter::Sync& completer) final;
  void Write(WriteRequestView request, WriteCompleter::Sync& completer) final;
  void Describe(DescribeCompleter::Sync& completer) final;

  void OpenClient(OpenClientRequestView request, OpenClientCompleter::Sync& completer) final;
  void ClrSetFeature(ClrSetFeatureRequestView request,
                     ClrSetFeatureCompleter::Sync& completer) final;
  void GetWindowSize(GetWindowSizeCompleter::Sync& completer) final;
  void MakeActive(MakeActiveRequestView request, MakeActiveCompleter::Sync& completer) final;
  void ReadEvents(ReadEventsCompleter::Sync& completer) final;
  void SetWindowSize(SetWindowSizeRequestView request,
                     SetWindowSizeCompleter::Sync& completer) final;

  // Create a new PtyClient
  zx_status_t CreateClient(uint32_t id,
                           fidl::ServerEnd<fuchsia_hardware_pty::Device> client_request);

  // Remove a PtyClient
  void RemoveClient(uint32_t id);

  // Called when data is written by the active client
  zx_status_t Recv(const void* data, size_t len, size_t* actual, bool* is_full);

  // Called when data is being sent to the active client
  zx_status_t Send(const void* data, size_t len, size_t* actual);

  void AssertWritableSignal() {
    local_.signal_peer(0, static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kWritable));
  }

  // Read all outstanding events, and reset the pending signal.
  uint32_t DrainEvents();

  // Called to make the given client active.  Any existing active client is
  // deactivated.  Returns ZX_ERR_NOT_FOUND if the requested id does not exist.
  zx_status_t MakeActive(uint32_t id);

  fuchsia_hardware_pty::wire::WindowSize window_size() { return size_; }

  [[nodiscard]] bool is_active(const PtyClient& client) const {
    return active_.has_value() && &active_.value().get() == &client;
  }

  [[nodiscard]] bool is_control(const PtyClient& client) const {
    return control_.has_value() && &control_.value().get() == &client;
  }

 private:
  // Called to make the given client active.  Any existing active client is
  // deactivated.
  void MakeActive(PtyClient& client);

  // remote_ is signaled to indicate to server connections various status
  // conditions.
  zx::eventpair local_, remote_;

  async_dispatcher_t* dispatcher_;

  // Data waiting to be read by a connection to the server.
  Fifo rx_fifo_;

  // Pending out-of-band events
  uint32_t events_ = 0;

  // List of all clients
  std::unordered_map<uint32_t, PtyClient> clients_;

  // Active client
  std::optional<std::reference_wrapper<PtyClient>> active_;

  // The control client is the client that receives events
  std::optional<std::reference_wrapper<PtyClient>> control_;

  // The dimensions (in characters) of the window
  fuchsia_hardware_pty::wire::WindowSize size_ = {};

  fidl::ServerBindingGroup<fuchsia_hardware_pty::Device> bindings_;
};

#endif  // SRC_BRINGUP_BIN_PTYSVC_PTY_SERVER_H_
