text: /**
   * This file is part of the "libterminal" project
   *   Copyright (c) 2019-2020 Christian Parpart <christian@parpart.family>
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  #pragma once
  
  #include <terminal/primitives.h>
  
  #include <crispy/logstore.h>
  
  #include <chrono>
  #include <optional>
  #include <string_view>
  
  namespace terminal
  {
  
  class Pty
  {
    public:
      virtual ~Pty() = default;
  
      /// Releases this PTY early.
      ///
      /// This is automatically invoked when the destructor is called.
      virtual void close() = 0;
  
      /// Returns true if the underlying PTY is closed, otherwise false.
      virtual bool isClosed() const = 0;
  
      /// Prepares PTY for use with a child process, therefore, closing the master end and
      /// doing some more prep work.
      ///
      /// Invoke this function after the respective child process has been fork()'ed.'
      virtual void prepareParentProcess() = 0;
  
      /// Prepares PTY for use inside a child process.
      ///
      /// That is, the current process must be already the child, i.e. via fork().
      virtual void prepareChildProcess() = 0;
  
      /// Reads from the terminal whatever has been written to from the other side of the terminal.
      ///
      /// @param _size   Capacity of parameter @p buf. At most @p size bytes will be stored into it.
      ///
      /// @returns view to the consumed buffer.
      virtual std::optional<std::string_view> read(size_t _size, std::chrono::milliseconds _timeout) = 0;
  
      /// Inerrupts the read() operation on this PTY if a read() is currently in progress.
      ///
      /// If no read() is currently being in progress, then this call
      /// will have no effect.
      ///
      /// @notice This is typically implemented using non-blocking I/O.
      virtual void wakeupReader() = 0;
  
      /// Writes to the PTY device, so the other end can read from it.
      ///
      /// @param buf    Buffer of data to be written.
      /// @param size   Number of bytes in @p buf to write.
      ///
      /// @returns Number of bytes written or -1 on error.
      virtual int write(char const* buf, size_t size) = 0;
  
      /// @returns current underlying window size in characters width and height.
      virtual PageSize pageSize() const noexcept = 0;
  
      /// Resizes underlying window buffer by given character width and height.
      virtual void resizeScreen(PageSize _cells, std::optional<ImageSize> _pixels = std::nullopt) = 0;
  };
  
  auto const inline PtyLog = logstore::Category("pty", "Logs general PTY informations.");
  auto const inline PtyInLog = logstore::Category("pty.input", "Logs PTY raw input.");
  auto const inline PtyOutLog = logstore::Category("pty.output", "Logs PTY raw output.");
  
  } // namespace terminal
  