//===-- IOStream.cpp --------------------------------------------*- C++ -*-===//
//
// 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 "IOStream.h"

#if defined(_WIN32)
#include <io.h>
#else
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#endif

#include <fstream>
#include <string>
#include <vector>

using namespace lldb_vscode;

StreamDescriptor::StreamDescriptor() = default;

StreamDescriptor::StreamDescriptor(StreamDescriptor &&other) {
  *this = std::move(other);
}

StreamDescriptor::~StreamDescriptor() {
  if (!m_close)
    return;

  if (m_is_socket)
#if defined(_WIN32)
    ::closesocket(m_socket);
#else
    ::close(m_socket);
#endif
  else
    ::close(m_fd);
}

StreamDescriptor &StreamDescriptor::operator=(StreamDescriptor &&other) {
  m_close = other.m_close;
  other.m_close = false;
  m_is_socket = other.m_is_socket;
  if (m_is_socket)
    m_socket = other.m_socket;
  else
    m_fd = other.m_fd;
  return *this;
}

StreamDescriptor StreamDescriptor::from_socket(SOCKET s, bool close) {
  StreamDescriptor sd;
  sd.m_is_socket = true;
  sd.m_socket = s;
  sd.m_close = close;
  return sd;
}

StreamDescriptor StreamDescriptor::from_file(int fd, bool close) {
  StreamDescriptor sd;
  sd.m_is_socket = false;
  sd.m_fd = fd;
  sd.m_close = close;
  return sd;
}

bool OutputStream::write_full(llvm::StringRef str) {
  while (!str.empty()) {
    int bytes_written = 0;
    if (descriptor.m_is_socket)
      bytes_written = ::send(descriptor.m_socket, str.data(), str.size(), 0);
    else
      bytes_written = ::write(descriptor.m_fd, str.data(), str.size());

    if (bytes_written < 0) {
      if (errno == EINTR || errno == EAGAIN)
        continue;
      return false;
    }
    str = str.drop_front(bytes_written);
  }

  return true;
}

bool InputStream::read_full(std::ofstream *log, size_t length,
                            std::string &text) {
  std::string data;
  data.resize(length);

  char *ptr = &data[0];
  while (length != 0) {
    int bytes_read = 0;
    if (descriptor.m_is_socket)
      bytes_read = ::recv(descriptor.m_socket, ptr, length, 0);
    else
      bytes_read = ::read(descriptor.m_fd, ptr, length);

    if (bytes_read == 0) {
      if (log)
        *log << "End of file (EOF) reading from input file.\n";
      return false;
    }
    if (bytes_read < 0) {
      int reason = 0;
#if defined(_WIN32)
      if (descriptor.m_is_socket)
        reason = WSAGetLastError();
      else
        reason = errno;
#else
      reason = errno;
      if (reason == EINTR || reason == EAGAIN)
        continue;
#endif

      if (log)
        *log << "Error " << reason << " reading from input file.\n";
      return false;
    }

    assert(bytes_read >= 0 && (size_t)bytes_read <= length);
    ptr += bytes_read;
    length -= bytes_read;
  }
  text += data;
  return true;
}

bool InputStream::read_line(std::ofstream *log, std::string &line) {
  line.clear();
  while (true) {
    if (!read_full(log, 1, line))
      return false;

    if (llvm::StringRef(line).endswith("\r\n"))
      break;
  }
  line.erase(line.size() - 2);
  return true;
}

bool InputStream::read_expected(std::ofstream *log, llvm::StringRef expected) {
  std::string result;
  if (!read_full(log, expected.size(), result))
    return false;
  if (expected != result) {
    if (log)
      *log << "Warning: Expected '" << expected.str() << "', got '" << result
           << "\n";
  }
  return true;
}
