//===-- RunInTerminal.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 "RunInTerminal.h"

#if LLVM_ON_UNIX
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif

#include <chrono>
#include <fstream>
#include <future>
#include <thread>

#include "llvm/Support/FileSystem.h"

#include "lldb/lldb-defines.h"

using namespace llvm;

namespace lldb_vscode {

const RunInTerminalMessagePid *RunInTerminalMessage::GetAsPidMessage() const {
  return static_cast<const RunInTerminalMessagePid *>(this);
}

const RunInTerminalMessageError *
RunInTerminalMessage::GetAsErrorMessage() const {
  return static_cast<const RunInTerminalMessageError *>(this);
}

RunInTerminalMessage::RunInTerminalMessage(RunInTerminalMessageKind kind)
    : kind(kind) {}

RunInTerminalMessagePid::RunInTerminalMessagePid(lldb::pid_t pid)
    : RunInTerminalMessage(eRunInTerminalMessageKindPID), pid(pid) {}

json::Value RunInTerminalMessagePid::ToJSON() const {
  return json::Object{{"kind", "pid"}, {"pid", static_cast<int64_t>(pid)}};
}

RunInTerminalMessageError::RunInTerminalMessageError(StringRef error)
    : RunInTerminalMessage(eRunInTerminalMessageKindError), error(error) {}

json::Value RunInTerminalMessageError::ToJSON() const {
  return json::Object{{"kind", "error"}, {"value", error}};
}

RunInTerminalMessageDidAttach::RunInTerminalMessageDidAttach()
    : RunInTerminalMessage(eRunInTerminalMessageKindDidAttach) {}

json::Value RunInTerminalMessageDidAttach::ToJSON() const {
  return json::Object{{"kind", "didAttach"}};
}

static Expected<RunInTerminalMessageUP>
ParseJSONMessage(const json::Value &json) {
  if (const json::Object *obj = json.getAsObject()) {
    if (Optional<StringRef> kind = obj->getString("kind")) {
      if (*kind == "pid") {
        if (Optional<int64_t> pid = obj->getInteger("pid"))
          return std::make_unique<RunInTerminalMessagePid>(
              static_cast<lldb::pid_t>(*pid));
      } else if (*kind == "error") {
        if (Optional<StringRef> error = obj->getString("error"))
          return std::make_unique<RunInTerminalMessageError>(*error);
      } else if (*kind == "didAttach") {
        return std::make_unique<RunInTerminalMessageDidAttach>();
      }
    }
  }

  return createStringError(inconvertibleErrorCode(),
                           "Incorrect JSON message: " + JSONToString(json));
}

static Expected<RunInTerminalMessageUP>
GetNextMessage(FifoFileIO &io, std::chrono::milliseconds timeout) {
  if (Expected<json::Value> json = io.ReadJSON(timeout))
    return ParseJSONMessage(*json);
  else
    return json.takeError();
}

static Error ToError(const RunInTerminalMessage &message) {
  if (message.kind == eRunInTerminalMessageKindError)
    return createStringError(inconvertibleErrorCode(),
                             message.GetAsErrorMessage()->error);
  return createStringError(inconvertibleErrorCode(),
                           "Unexpected JSON message: " +
                               JSONToString(message.ToJSON()));
}

RunInTerminalLauncherCommChannel::RunInTerminalLauncherCommChannel(
    StringRef comm_file)
    : m_io(comm_file, "debug adaptor") {}

Error RunInTerminalLauncherCommChannel::WaitUntilDebugAdaptorAttaches(
    std::chrono::milliseconds timeout) {
  if (Expected<RunInTerminalMessageUP> message =
          GetNextMessage(m_io, timeout)) {
    if (message.get()->kind == eRunInTerminalMessageKindDidAttach)
      return Error::success();
    else
      return ToError(*message.get());
  } else
    return message.takeError();
}

Error RunInTerminalLauncherCommChannel::NotifyPid() {
  return m_io.SendJSON(RunInTerminalMessagePid(getpid()).ToJSON());
}

void RunInTerminalLauncherCommChannel::NotifyError(StringRef error) {
  if (Error err = m_io.SendJSON(RunInTerminalMessageError(error).ToJSON(),
                                std::chrono::seconds(2)))
    llvm::errs() << llvm::toString(std::move(err)) << "\n";
}

RunInTerminalDebugAdapterCommChannel::RunInTerminalDebugAdapterCommChannel(
    StringRef comm_file)
    : m_io(comm_file, "runInTerminal launcher") {}

// Can't use \a std::future<llvm::Error> because it doesn't compile on Windows
std::future<lldb::SBError>
RunInTerminalDebugAdapterCommChannel::NotifyDidAttach() {
  return std::async(std::launch::async, [&]() {
    lldb::SBError error;
    if (llvm::Error err =
            m_io.SendJSON(RunInTerminalMessageDidAttach().ToJSON()))
      error.SetErrorString(llvm::toString(std::move(err)).c_str());
    return error;
  });
}

Expected<lldb::pid_t> RunInTerminalDebugAdapterCommChannel::GetLauncherPid() {
  if (Expected<RunInTerminalMessageUP> message =
          GetNextMessage(m_io, std::chrono::seconds(20))) {
    if (message.get()->kind == eRunInTerminalMessageKindPID)
      return message.get()->GetAsPidMessage()->pid;
    return ToError(*message.get());
  } else {
    return message.takeError();
  }
}

std::string RunInTerminalDebugAdapterCommChannel::GetLauncherError() {
  // We know there's been an error, so a small timeout is enough.
  if (Expected<RunInTerminalMessageUP> message =
          GetNextMessage(m_io, std::chrono::seconds(1)))
    return toString(ToError(*message.get()));
  else
    return toString(message.takeError());
}

Expected<std::shared_ptr<FifoFile>> CreateRunInTerminalCommFile() {
  SmallString<256> comm_file;
  if (std::error_code EC = sys::fs::getPotentiallyUniqueTempFileName(
          "lldb-vscode-run-in-terminal-comm", "", comm_file))
    return createStringError(EC, "Error making unique file name for "
                                 "runInTerminal communication files");

  return CreateFifoFile(comm_file.str());
}

} // namespace lldb_vscode
