//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/windows/ConnectionConPTYWindows.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Timeout.h"

#include <cstring>

using namespace lldb;
using namespace lldb_private;

ConnectionConPTY::ConnectionConPTY(std::shared_ptr<PseudoConsole> pty)
    : ConnectionGenericFile(pty->GetSTDOUTHandle(), false), m_pty(pty) {}

ConnectionConPTY::~ConnectionConPTY() = default;

lldb::ConnectionStatus ConnectionConPTY::Connect(llvm::StringRef s,
                                                 Status *error_ptr) {
  if (m_pty->IsConnected())
    return eConnectionStatusSuccess;
  return eConnectionStatusNoConnection;
}

lldb::ConnectionStatus ConnectionConPTY::Disconnect(Status *error_ptr) {
  m_pty->Close();
  return eConnectionStatusSuccess;
}

size_t ConnectionConPTY::Read(void *dst, size_t dst_len,
                              const Timeout<std::micro> &timeout,
                              lldb::ConnectionStatus &status,
                              Status *error_ptr) {
  {
    std::unique_lock<std::mutex> guard(m_pty->GetMutex());
    if (m_pty->IsStopping())
      m_pty->GetCV().wait(guard, [this] { return !m_pty->IsStopping(); });
    if (!m_pty->IsConnected()) {
      status = eConnectionStatusEndOfFile;
      return 0;
    }
  }

  char *out = static_cast<char *>(dst);
  size_t bytes_read =
      ConnectionGenericFile::Read(out, dst_len, timeout, status, error_ptr);

  if (bytes_read > 0) {
    StripConPTYSequences(out, bytes_read, !m_conpty_sequences_stripped);
    m_conpty_sequences_stripped = true;
  }

  return bytes_read;
}

size_t ConnectionConPTY::Write(const void *src, size_t src_len,
                               lldb::ConnectionStatus &status,
                               Status *error_ptr) {
  if (!m_pty || !m_pty->IsConnected()) {
    status = eConnectionStatusNoConnection;
    if (error_ptr)
      *error_ptr = Status::FromErrorString("ConPTY not connected");
    return 0;
  }
  HANDLE stdin_handle = m_pty->GetSTDINHandle();
  if (stdin_handle == INVALID_HANDLE_VALUE || stdin_handle == nullptr) {
    status = eConnectionStatusNoConnection;
    if (error_ptr)
      *error_ptr = Status::FromErrorString("ConPTY STDIN handle is invalid");
    return 0;
  }
  DWORD written = 0;
  if (!::WriteFile(stdin_handle, src, static_cast<DWORD>(src_len), &written,
                   nullptr)) {
    DWORD err = ::GetLastError();
    status = (err == ERROR_BROKEN_PIPE || err == ERROR_NO_DATA)
                 ? eConnectionStatusEndOfFile
                 : eConnectionStatusError;
    if (error_ptr)
      *error_ptr = Status(err, lldb::eErrorTypeWin32);
    return written;
  }
  status = eConnectionStatusSuccess;
  return written;
}
