// 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_CLIENT_H_
#define SRC_BRINGUP_BIN_PTYSVC_PTY_CLIENT_H_

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

#include "fifo.h"
#include "pty-server.h"

class PtyClient : public fidl::WireServer<fuchsia_hardware_pty::Device> {
 public:
  PtyClient(std::shared_ptr<PtyServer>, uint32_t id, zx::eventpair local, zx::eventpair remote);

  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);

  // fuchsia.hardware.pty.Device.
  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;

  Fifo* rx_fifo() { return &rx_fifo_; }

  void AssertHangupSignal() {
    ClearSetFlags(0, kFlagPeerClosed);
    local_.signal_peer(static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kWritable),
                       static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kHangup));
  }
  void AssertActiveHungup() {
    local_.signal_peer(0, static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kOob |
                                                    fuchsia_device::wire::DeviceSignal::kHangup));
  }
  void AssertReadableSignal() {
    local_.signal_peer(0, static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kReadable));
  }
  void AssertWritableSignal() {
    local_.signal_peer(0, static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kWritable));
  }
  void AssertEventSignal() {
    local_.signal_peer(0, static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kOob));
  }

  void DeAssertReadableSignal() {
    local_.signal_peer(static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kReadable), 0);
  }
  void DeAssertWritableSignal() {
    local_.signal_peer(static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kWritable), 0);
  }
  void DeAssertEventSignal() {
    local_.signal_peer(static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kOob), 0);
  }

  void ClearSetFlags(uint32_t clr, uint32_t set) { flags_ = (flags_ & ~clr) | set; }
  uint32_t flags() const { return flags_; }
  [[nodiscard]] bool in_raw_mode() const { return flags_ & kFlagRawMode; }
  [[nodiscard]] bool is_peer_closed() const { return flags_ & kFlagPeerClosed; }

  // Ensure READABLE/WRITABLE signals are properly asserted based on active
  // status and rx_fifo status.
  void AdjustSignals();

  [[nodiscard]] bool is_active() { return server().is_active(*this); }
  [[nodiscard]] bool is_control() { return server().is_control(*this); }

  PtyServer& server() { return *server_; }

 private:
  zx_status_t WriteChunk(const void* buf, size_t count, size_t* actual);

  std::shared_ptr<PtyServer> server_;
  const uint32_t id_;

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

  static constexpr uint32_t kFlagRawMode = 0x00000001u;
  static_assert(kFlagRawMode == fuchsia_hardware_pty::wire::kFeatureRaw);
  static constexpr uint32_t kFlagPeerClosed = 0x00000002u;

  uint32_t flags_ = 0;
  Fifo rx_fifo_;

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

#endif  // SRC_BRINGUP_BIN_PTYSVC_PTY_CLIENT_H_
