//===-- IOHandler.cpp -----------------------------------------------------===//
//
// 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/Core/IOHandler.h"

#if defined(__APPLE__)
#include <deque>
#endif
#include <string>

#include "lldb/Core/Debugger.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/File.h"
#include "lldb/Host/StreamFile.h"
#include "lldb/Utility/AnsiTerminal.h"
#include "lldb/Utility/Predicate.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringList.h"
#include "lldb/lldb-forward.h"

#if LLDB_ENABLE_LIBEDIT
#include "lldb/Host/Editline.h"
#endif
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "llvm/ADT/StringRef.h"

#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
#endif

#include <memory>
#include <mutex>
#include <optional>

#include <cassert>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <type_traits>

using namespace lldb;
using namespace lldb_private;
using llvm::StringRef;

IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type)
    : IOHandler(debugger, type,
                FileSP(),               // Adopt STDIN from top input reader
                LockableStreamFileSP(), // Adopt STDOUT from top input reader
                LockableStreamFileSP(), // Adopt STDERR from top input reader
                0                       // Flags

      ) {}

IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type,
                     const lldb::FileSP &input_sp,
                     const lldb::LockableStreamFileSP &output_sp,
                     const lldb::LockableStreamFileSP &error_sp, uint32_t flags)
    : m_debugger(debugger), m_input_sp(input_sp), m_output_sp(output_sp),
      m_error_sp(error_sp), m_popped(false), m_flags(flags), m_type(type),
      m_user_data(nullptr), m_done(false), m_active(false) {
  // If any files are not specified, then adopt them from the top input reader.
  if (!m_input_sp || !m_output_sp || !m_error_sp)
    debugger.AdoptTopIOHandlerFilesIfInvalid(m_input_sp, m_output_sp,
                                             m_error_sp);
}

IOHandler::~IOHandler() = default;

int IOHandler::GetInputFD() {
  return (m_input_sp ? m_input_sp->GetDescriptor() : -1);
}

int IOHandler::GetOutputFD() {
  return (m_output_sp ? m_output_sp->GetUnlockedFile().GetDescriptor() : -1);
}

int IOHandler::GetErrorFD() {
  return (m_error_sp ? m_error_sp->GetUnlockedFile().GetDescriptor() : -1);
}

FileSP IOHandler::GetInputFileSP() { return m_input_sp; }

LockableStreamFileSP IOHandler::GetOutputStreamFileSP() { return m_output_sp; }

LockableStreamFileSP IOHandler::GetErrorStreamFileSP() { return m_error_sp; }

bool IOHandler::GetIsInteractive() {
  return GetInputFileSP() ? GetInputFileSP()->GetIsInteractive() : false;
}

bool IOHandler::GetIsRealTerminal() {
  return GetInputFileSP() ? GetInputFileSP()->GetIsRealTerminal() : false;
}

void IOHandler::SetPopped(bool b) { m_popped.SetValue(b, eBroadcastOnChange); }

void IOHandler::WaitForPop() { m_popped.WaitForValueEqualTo(true); }

void IOHandler::PrintAsync(const char *s, size_t len, bool is_stdout) {
  lldb::LockableStreamFileSP stream_sp = is_stdout ? m_output_sp : m_error_sp;
  LockedStreamFile locked_Stream = stream_sp->Lock();
  locked_Stream.Write(s, len);
}

bool IOHandlerStack::PrintAsync(const char *s, size_t len, bool is_stdout) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  if (!m_top)
    return false;
  m_top->PrintAsync(s, len, is_stdout);
  return true;
}

IOHandlerConfirm::IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt,
                                   bool default_response)
    : IOHandlerEditline(
          debugger, IOHandler::Type::Confirm,
          nullptr, // nullptr editline_name means no history loaded/saved
          llvm::StringRef(), // No prompt
          llvm::StringRef(), // No continuation prompt
          false,             // Multi-line
          false, // Don't colorize the prompt (i.e. the confirm message.)
          0, *this),
      m_default_response(default_response), m_user_response(default_response) {
  StreamString prompt_stream;
  prompt_stream.PutCString(prompt);
  if (m_default_response)
    prompt_stream.Printf(": [Y/n] ");
  else
    prompt_stream.Printf(": [y/N] ");

  SetPrompt(prompt_stream.GetString());
}

IOHandlerConfirm::~IOHandlerConfirm() = default;

void IOHandlerConfirm::IOHandlerComplete(IOHandler &io_handler,
                                         CompletionRequest &request) {
  if (request.GetRawCursorPos() != 0)
    return;
  request.AddCompletion(m_default_response ? "y" : "n");
}

void IOHandlerConfirm::IOHandlerInputComplete(IOHandler &io_handler,
                                              std::string &line) {
  if (line.empty()) {
    // User just hit enter, set the response to the default
    m_user_response = m_default_response;
    io_handler.SetIsDone(true);
    return;
  }

  if (line.size() == 1) {
    switch (line[0]) {
    case 'y':
    case 'Y':
      m_user_response = true;
      io_handler.SetIsDone(true);
      return;
    case 'n':
    case 'N':
      m_user_response = false;
      io_handler.SetIsDone(true);
      return;
    default:
      break;
    }
  }

  if (line == "yes" || line == "YES" || line == "Yes") {
    m_user_response = true;
    io_handler.SetIsDone(true);
  } else if (line == "no" || line == "NO" || line == "No") {
    m_user_response = false;
    io_handler.SetIsDone(true);
  }
}

std::optional<std::string>
IOHandlerDelegate::IOHandlerSuggestion(IOHandler &io_handler,
                                       llvm::StringRef line) {
  return io_handler.GetDebugger()
      .GetCommandInterpreter()
      .GetAutoSuggestionForCommand(line);
}

void IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler,
                                          CompletionRequest &request) {
  switch (m_completion) {
  case Completion::None:
    break;
  case Completion::LLDBCommand:
    io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion(request);
    break;
  case Completion::Expression:
    lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
        io_handler.GetDebugger().GetCommandInterpreter(),
        lldb::eVariablePathCompletion, request, nullptr);
    break;
  }
}

IOHandlerEditline::IOHandlerEditline(
    Debugger &debugger, IOHandler::Type type,
    const char *editline_name, // Used for saving history files
    llvm::StringRef prompt, llvm::StringRef continuation_prompt,
    bool multi_line, bool color, uint32_t line_number_start,
    IOHandlerDelegate &delegate)
    : IOHandlerEditline(
          debugger, type,
          FileSP(),               // Inherit input from top input reader
          LockableStreamFileSP(), // Inherit output from top input reader
          LockableStreamFileSP(), // Inherit error from top input reader
          0,                      // Flags
          editline_name,          // Used for saving history files
          prompt, continuation_prompt, multi_line, color, line_number_start,
          delegate) {}

IOHandlerEditline::IOHandlerEditline(
    Debugger &debugger, IOHandler::Type type, const lldb::FileSP &input_sp,
    const lldb::LockableStreamFileSP &output_sp,
    const lldb::LockableStreamFileSP &error_sp, uint32_t flags,
    const char *editline_name, // Used for saving history files
    llvm::StringRef prompt, llvm::StringRef continuation_prompt,
    bool multi_line, bool color, uint32_t line_number_start,
    IOHandlerDelegate &delegate)
    : IOHandler(debugger, type, input_sp, output_sp, error_sp, flags),
#if LLDB_ENABLE_LIBEDIT
      m_editline_up(),
#endif
      m_delegate(delegate), m_prompt(), m_continuation_prompt(),
      m_current_lines_ptr(nullptr), m_base_line_number(line_number_start),
      m_curr_line_idx(UINT32_MAX), m_multi_line(multi_line), m_color(color),
      m_interrupt_exits(true) {
  SetPrompt(prompt);

#if LLDB_ENABLE_LIBEDIT
  const bool use_editline = m_input_sp && m_output_sp && m_error_sp &&
                            m_input_sp->GetIsRealTerminal();
  if (use_editline) {
    m_editline_up = std::make_unique<Editline>(
        editline_name, m_input_sp ? m_input_sp->GetStream() : nullptr,
        m_output_sp, m_error_sp, m_color);
    m_editline_up->SetIsInputCompleteCallback(
        [this](Editline *editline, StringList &lines) {
          return this->IsInputCompleteCallback(editline, lines);
        });

    m_editline_up->SetAutoCompleteCallback([this](CompletionRequest &request) {
      this->AutoCompleteCallback(request);
    });
    m_editline_up->SetRedrawCallback([this]() { this->RedrawCallback(); });

    if (debugger.GetUseAutosuggestion()) {
      m_editline_up->SetSuggestionCallback([this](llvm::StringRef line) {
        return this->SuggestionCallback(line);
      });
      m_editline_up->SetSuggestionAnsiPrefix(ansi::FormatAnsiTerminalCodes(
          debugger.GetAutosuggestionAnsiPrefix()));
      m_editline_up->SetSuggestionAnsiSuffix(ansi::FormatAnsiTerminalCodes(
          debugger.GetAutosuggestionAnsiSuffix()));
    }
    // See if the delegate supports fixing indentation
    const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters();
    if (indent_chars) {
      // The delegate does support indentation, hook it up so when any
      // indentation character is typed, the delegate gets a chance to fix it
      FixIndentationCallbackType f = [this](Editline *editline,
                                            const StringList &lines,
                                            int cursor_position) {
        return this->FixIndentationCallback(editline, lines, cursor_position);
      };
      m_editline_up->SetFixIndentationCallback(std::move(f), indent_chars);
    }
  }
#endif
  SetBaseLineNumber(m_base_line_number);
  SetPrompt(prompt);
  SetContinuationPrompt(continuation_prompt);
}

IOHandlerEditline::~IOHandlerEditline() {
#if LLDB_ENABLE_LIBEDIT
  m_editline_up.reset();
#endif
}

void IOHandlerEditline::Activate() {
  IOHandler::Activate();
  m_delegate.IOHandlerActivated(*this, GetIsInteractive());
}

void IOHandlerEditline::Deactivate() {
  IOHandler::Deactivate();
  m_delegate.IOHandlerDeactivated(*this);
}

void IOHandlerEditline::TerminalSizeChanged() {
#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up)
    m_editline_up->TerminalSizeChanged();
#endif
}

// Split out a line from the buffer, if there is a full one to get.
static std::optional<std::string> SplitLine(std::string &line_buffer) {
  size_t pos = line_buffer.find('\n');
  if (pos == std::string::npos)
    return std::nullopt;
  std::string line =
      std::string(StringRef(line_buffer.c_str(), pos).rtrim("\n\r"));
  line_buffer = line_buffer.substr(pos + 1);
  return line;
}

// If the final line of the file ends without a end-of-line, return
// it as a line anyway.
static std::optional<std::string> SplitLineEOF(std::string &line_buffer) {
  if (llvm::all_of(line_buffer, llvm::isSpace))
    return std::nullopt;
  std::string line = std::move(line_buffer);
  line_buffer.clear();
  return line;
}

bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) {
#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up) {
    return m_editline_up->GetLine(line, interrupted);
  }
#endif

  line.clear();

  if (GetIsInteractive()) {
    const char *prompt = nullptr;

    if (m_multi_line && m_curr_line_idx > 0)
      prompt = GetContinuationPrompt();

    if (prompt == nullptr)
      prompt = GetPrompt();

    if (prompt && prompt[0]) {
      if (m_output_sp) {
        LockedStreamFile locked_stream = m_output_sp->Lock();
        locked_stream.Printf("%s", prompt);
      }
    }
  }

  std::optional<std::string> got_line = SplitLine(m_line_buffer);

  if (!got_line && !m_input_sp) {
    // No more input file, we are done...
    SetIsDone(true);
    return false;
  }

  FILE *in = m_input_sp ? m_input_sp->GetStream() : nullptr;
  char buffer[256];

  if (!got_line && !in && m_input_sp) {
    // there is no FILE*, fall back on just reading bytes from the stream.
    while (!got_line) {
      size_t bytes_read = sizeof(buffer);
      Status error = m_input_sp->Read((void *)buffer, bytes_read);
      if (error.Success() && !bytes_read) {
        got_line = SplitLineEOF(m_line_buffer);
        break;
      }
      if (error.Fail())
        break;
      m_line_buffer += StringRef(buffer, bytes_read);
      got_line = SplitLine(m_line_buffer);
    }
  }

  if (!got_line && in) {
    while (!got_line) {
      char *r = fgets(buffer, sizeof(buffer), in);
#ifdef _WIN32
      // ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED
      // according to the docs on MSDN. However, this has evidently been a
      // known bug since Windows 8. Therefore, we can't detect if a signal
      // interrupted in the fgets. So pressing ctrl-c causes the repl to end
      // and the process to exit. A temporary workaround is just to attempt to
      // fgets twice until this bug is fixed.
      if (r == nullptr)
        r = fgets(buffer, sizeof(buffer), in);
      // this is the equivalent of EINTR for Windows
      if (r == nullptr && GetLastError() == ERROR_OPERATION_ABORTED)
        continue;
#endif
      if (r == nullptr) {
        if (ferror(in) && errno == EINTR)
          continue;
        if (feof(in))
          got_line = SplitLineEOF(m_line_buffer);
        break;
      }
      m_line_buffer += buffer;
      got_line = SplitLine(m_line_buffer);
    }
  }

  if (got_line) {
    line = *got_line;
  }

  return (bool)got_line;
}

#if LLDB_ENABLE_LIBEDIT
bool IOHandlerEditline::IsInputCompleteCallback(Editline *editline,
                                                StringList &lines) {
  return m_delegate.IOHandlerIsInputComplete(*this, lines);
}

int IOHandlerEditline::FixIndentationCallback(Editline *editline,
                                              const StringList &lines,
                                              int cursor_position) {
  return m_delegate.IOHandlerFixIndentation(*this, lines, cursor_position);
}

std::optional<std::string>
IOHandlerEditline::SuggestionCallback(llvm::StringRef line) {
  return m_delegate.IOHandlerSuggestion(*this, line);
}

void IOHandlerEditline::AutoCompleteCallback(CompletionRequest &request) {
  m_delegate.IOHandlerComplete(*this, request);
}

void IOHandlerEditline::RedrawCallback() {
  m_debugger.RedrawStatusline(/*update=*/false);
}

#endif

const char *IOHandlerEditline::GetPrompt() {
#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up) {
    return m_editline_up->GetPrompt();
  } else {
#endif
    if (m_prompt.empty())
      return nullptr;
#if LLDB_ENABLE_LIBEDIT
  }
#endif
  return m_prompt.c_str();
}

bool IOHandlerEditline::SetPrompt(llvm::StringRef prompt) {
  m_prompt = std::string(prompt);

#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up) {
    m_editline_up->SetPrompt(m_prompt.empty() ? nullptr : m_prompt.c_str());
    m_editline_up->SetPromptAnsiPrefix(
        ansi::FormatAnsiTerminalCodes(m_debugger.GetPromptAnsiPrefix()));
    m_editline_up->SetPromptAnsiSuffix(
        ansi::FormatAnsiTerminalCodes(m_debugger.GetPromptAnsiSuffix()));
  }
#endif
  return true;
}

const char *IOHandlerEditline::GetContinuationPrompt() {
  return (m_continuation_prompt.empty() ? nullptr
                                        : m_continuation_prompt.c_str());
}

void IOHandlerEditline::SetContinuationPrompt(llvm::StringRef prompt) {
  m_continuation_prompt = std::string(prompt);

#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up)
    m_editline_up->SetContinuationPrompt(m_continuation_prompt.empty()
                                             ? nullptr
                                             : m_continuation_prompt.c_str());
#endif
}

void IOHandlerEditline::SetBaseLineNumber(uint32_t line) {
  m_base_line_number = line;
}

uint32_t IOHandlerEditline::GetCurrentLineIndex() const {
#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up)
    return m_editline_up->GetCurrentLine();
#endif
  return m_curr_line_idx;
}

StringList IOHandlerEditline::GetCurrentLines() const {
#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up)
    return m_editline_up->GetInputAsStringList();
#endif
  // When libedit is not used, the current lines can be gotten from
  // `m_current_lines_ptr`, which is updated whenever a new line is processed.
  // This doesn't happen when libedit is used, in which case
  // `m_current_lines_ptr` is only updated when the full input is terminated.

  if (m_current_lines_ptr)
    return *m_current_lines_ptr;
  return StringList();
}

bool IOHandlerEditline::GetLines(StringList &lines, bool &interrupted) {
  m_current_lines_ptr = &lines;

  bool success = false;
#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up) {
    return m_editline_up->GetLines(m_base_line_number, lines, interrupted);
  } else {
#endif
    bool done = false;
    Status error;

    while (!done) {
      // Show line numbers if we are asked to
      std::string line;
      if (m_base_line_number > 0 && GetIsInteractive()) {
        if (m_output_sp) {
          LockedStreamFile locked_stream = m_output_sp->Lock();
          locked_stream.Printf("%u%s",
                               m_base_line_number + (uint32_t)lines.GetSize(),
                               GetPrompt() == nullptr ? " " : "");
        }
      }

      m_curr_line_idx = lines.GetSize();

      bool interrupted = false;
      if (GetLine(line, interrupted) && !interrupted) {
        lines.AppendString(line);
        done = m_delegate.IOHandlerIsInputComplete(*this, lines);
      } else {
        done = true;
      }
    }
    success = lines.GetSize() > 0;
#if LLDB_ENABLE_LIBEDIT
  }
#endif
  return success;
}

// Each IOHandler gets to run until it is done. It should read data from the
// "in" and place output into "out" and "err and return when done.
void IOHandlerEditline::Run() {
  std::string line;
  while (IsActive()) {
    bool interrupted = false;
    if (m_multi_line) {
      StringList lines;
      if (GetLines(lines, interrupted)) {
        if (interrupted) {
          m_done = m_interrupt_exits;
          m_delegate.IOHandlerInputInterrupted(*this, line);

        } else {
          line = lines.CopyList();
          m_delegate.IOHandlerInputComplete(*this, line);
        }
      } else {
        m_done = true;
      }
    } else {
      if (GetLine(line, interrupted)) {
        if (interrupted)
          m_delegate.IOHandlerInputInterrupted(*this, line);
        else
          m_delegate.IOHandlerInputComplete(*this, line);
      } else {
        m_done = true;
      }
    }
  }
}

void IOHandlerEditline::Cancel() {
#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up)
    m_editline_up->Cancel();
#endif
}

bool IOHandlerEditline::Interrupt() {
  // Let the delgate handle it first
  if (m_delegate.IOHandlerInterrupt(*this))
    return true;

#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up)
    return m_editline_up->Interrupt();
#endif
  return false;
}

void IOHandlerEditline::GotEOF() {
#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up)
    m_editline_up->Interrupt();
#endif
}

void IOHandlerEditline::PrintAsync(const char *s, size_t len, bool is_stdout) {
#if LLDB_ENABLE_LIBEDIT
  if (m_editline_up) {
    lldb::LockableStreamFileSP stream_sp = is_stdout ? m_output_sp : m_error_sp;
    m_editline_up->PrintAsync(stream_sp, s, len);
  } else
#endif
  {
#ifdef _WIN32
    const char *prompt = GetPrompt();
    if (prompt) {
      // Back up over previous prompt using Windows API
      CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
      HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
      GetConsoleScreenBufferInfo(console_handle, &screen_buffer_info);
      COORD coord = screen_buffer_info.dwCursorPosition;
      coord.X -= strlen(prompt);
      if (coord.X < 0)
        coord.X = 0;
      SetConsoleCursorPosition(console_handle, coord);
    }
#endif
    IOHandler::PrintAsync(s, len, is_stdout);
#ifdef _WIN32
    if (prompt)
      IOHandler::PrintAsync(prompt, strlen(prompt), is_stdout);
#endif
  }
}
