//===-- source/Host/windows/Host.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/Host/windows/AutoHandle.h"
#include "lldb/Host/windows/windows.h"
#include <stdio.h>

#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/ProcessLaunchInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"

#include "llvm/Support/ConvertUTF.h"

// Windows includes
#include <tlhelp32.h>

using namespace lldb;
using namespace lldb_private;

namespace {
bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) {
  // Open the PE File as a binary file, and parse just enough information to
  // determine the machine type.
  auto imageBinaryP = FileSystem::Instance().Open(
      executable, File::eOpenOptionRead, lldb::eFilePermissionsUserRead);
  if (!imageBinaryP)
    return llvm::errorToBool(imageBinaryP.takeError());
  File &imageBinary = *imageBinaryP.get();
  imageBinary.SeekFromStart(0x3c);
  int32_t peOffset = 0;
  uint32_t peHead = 0;
  uint16_t machineType = 0;
  size_t readSize = sizeof(peOffset);
  imageBinary.Read(&peOffset, readSize);
  imageBinary.SeekFromStart(peOffset);
  imageBinary.Read(&peHead, readSize);
  if (peHead != 0x00004550) // "PE\0\0", little-endian
    return false;           // Status: Can't find PE header
  readSize = 2;
  imageBinary.Read(&machineType, readSize);
  triple.setVendor(llvm::Triple::PC);
  triple.setOS(llvm::Triple::Win32);
  triple.setArch(llvm::Triple::UnknownArch);
  if (machineType == 0x8664)
    triple.setArch(llvm::Triple::x86_64);
  else if (machineType == 0x14c)
    triple.setArch(llvm::Triple::x86);
  else if (machineType == 0x1c4)
    triple.setArch(llvm::Triple::arm);
  else if (machineType == 0xaa64)
    triple.setArch(llvm::Triple::aarch64);

  return true;
}

bool GetExecutableForProcess(const AutoHandle &handle, std::string &path) {
  // Get the process image path.  MAX_PATH isn't long enough, paths can
  // actually be up to 32KB.
  std::vector<wchar_t> buffer(PATH_MAX);
  DWORD dwSize = buffer.size();
  if (!::QueryFullProcessImageNameW(handle.get(), 0, &buffer[0], &dwSize))
    return false;
  return llvm::convertWideToUTF8(buffer.data(), path);
}

void GetProcessExecutableAndTriple(const AutoHandle &handle,
                                   ProcessInstanceInfo &process) {
  // We may not have permissions to read the path from the process.  So start
  // off by setting the executable file to whatever Toolhelp32 gives us, and
  // then try to enhance this with more detailed information, but fail
  // gracefully.
  std::string executable;
  llvm::Triple triple;
  triple.setVendor(llvm::Triple::PC);
  triple.setOS(llvm::Triple::Win32);
  triple.setArch(llvm::Triple::UnknownArch);
  if (GetExecutableForProcess(handle, executable)) {
    FileSpec executableFile(executable.c_str());
    process.SetExecutableFile(executableFile, true);
    GetTripleForProcess(executableFile, triple);
  }
  process.SetArchitecture(ArchSpec(triple));

  // TODO(zturner): Add the ability to get the process user name.
}
}

lldb::thread_t Host::GetCurrentThread() {
  return lldb::thread_t(::GetCurrentThread());
}

void Host::Kill(lldb::pid_t pid, int signo) {
  TerminateProcess((HANDLE)pid, 1);
}

const char *Host::GetSignalAsCString(int signo) { return NULL; }

FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
  FileSpec module_filespec;

  HMODULE hmodule = NULL;
  if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
                           (LPCTSTR)host_addr, &hmodule))
    return module_filespec;

  std::vector<wchar_t> buffer(PATH_MAX);
  DWORD chars_copied = 0;
  do {
    chars_copied = ::GetModuleFileNameW(hmodule, &buffer[0], buffer.size());
    if (chars_copied == buffer.size() &&
        ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      buffer.resize(buffer.size() * 2);
  } while (chars_copied >= buffer.size());
  std::string path;
  if (!llvm::convertWideToUTF8(buffer.data(), path))
    return module_filespec;
  module_filespec.SetFile(path, FileSpec::Style::native);
  return module_filespec;
}

uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
                                 ProcessInstanceInfoList &process_infos) {
  process_infos.clear();

  AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
  if (!snapshot.IsValid())
    return 0;

  PROCESSENTRY32W pe = {};
  pe.dwSize = sizeof(PROCESSENTRY32W);
  if (Process32FirstW(snapshot.get(), &pe)) {
    do {
      AutoHandle handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
                                      pe.th32ProcessID),
                        nullptr);

      ProcessInstanceInfo process;
      std::string exeFile;
      llvm::convertWideToUTF8(pe.szExeFile, exeFile);
      process.SetExecutableFile(FileSpec(exeFile), true);
      process.SetProcessID(pe.th32ProcessID);
      process.SetParentProcessID(pe.th32ParentProcessID);
      GetProcessExecutableAndTriple(handle, process);

      if (match_info.MatchAllProcesses() || match_info.Matches(process))
        process_infos.push_back(process);
    } while (Process32NextW(snapshot.get(), &pe));
  }
  return process_infos.size();
}

bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
  process_info.Clear();

  AutoHandle handle(
      ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid),
      nullptr);
  if (!handle.IsValid())
    return false;

  process_info.SetProcessID(pid);
  GetProcessExecutableAndTriple(handle, process_info);

  // Need to read the PEB to get parent process and command line arguments.

  AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
  if (!snapshot.IsValid())
    return false;

  PROCESSENTRY32W pe;
  pe.dwSize = sizeof(PROCESSENTRY32W);
  if (Process32FirstW(snapshot.get(), &pe)) {
    do {
      if (pe.th32ProcessID == pid) {
        process_info.SetParentProcessID(pe.th32ParentProcessID);
        return true;
      }
    } while (Process32NextW(snapshot.get(), &pe));
  }

  return false;
}

llvm::Expected<HostThread> Host::StartMonitoringChildProcess(
    const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
    bool monitor_signals) {
  return HostThread();
}

Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
  Status error;
  if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
    FileSpec expand_tool_spec = HostInfo::GetSupportExeDir();
    if (!expand_tool_spec) {
      error.SetErrorString("could not find support executable directory for "
                           "the lldb-argdumper tool");
      return error;
    }
    expand_tool_spec.AppendPathComponent("lldb-argdumper.exe");
    if (!FileSystem::Instance().Exists(expand_tool_spec)) {
      error.SetErrorString("could not find the lldb-argdumper tool");
      return error;
    }

    std::string quoted_cmd_string;
    launch_info.GetArguments().GetQuotedCommandString(quoted_cmd_string);
    std::replace(quoted_cmd_string.begin(), quoted_cmd_string.end(), '\\', '/');
    StreamString expand_command;

    expand_command.Printf("\"%s\" %s", expand_tool_spec.GetPath().c_str(),
                          quoted_cmd_string.c_str());

    int status;
    std::string output;
    std::string command = expand_command.GetString().str();
    Status e =
        RunShellCommand(command.c_str(), launch_info.GetWorkingDirectory(),
                        &status, nullptr, &output, std::chrono::seconds(10));

    if (e.Fail())
      return e;

    if (status != 0) {
      error.SetErrorStringWithFormat("lldb-argdumper exited with error %d",
                                     status);
      return error;
    }

    auto data_sp = StructuredData::ParseJSON(output);
    if (!data_sp) {
      error.SetErrorString("invalid JSON");
      return error;
    }

    auto dict_sp = data_sp->GetAsDictionary();
    if (!data_sp) {
      error.SetErrorString("invalid JSON");
      return error;
    }

    auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments");
    if (!args_sp) {
      error.SetErrorString("invalid JSON");
      return error;
    }

    auto args_array_sp = args_sp->GetAsArray();
    if (!args_array_sp) {
      error.SetErrorString("invalid JSON");
      return error;
    }

    launch_info.GetArguments().Clear();

    for (size_t i = 0; i < args_array_sp->GetSize(); i++) {
      auto item_sp = args_array_sp->GetItemAtIndex(i);
      if (!item_sp)
        continue;
      auto str_sp = item_sp->GetAsString();
      if (!str_sp)
        continue;

      launch_info.GetArguments().AppendArgument(str_sp->GetValue());
    }
  }

  return error;
}

Environment Host::GetEnvironment() {
  Environment env;
  // The environment block on Windows is a contiguous buffer of NULL terminated
  // strings, where the end of the environment block is indicated by two
  // consecutive NULLs.
  LPWCH environment_block = ::GetEnvironmentStringsW();
  while (*environment_block != L'\0') {
    std::string current_var;
    auto current_var_size = wcslen(environment_block) + 1;
    if (!llvm::convertWideToUTF8(environment_block, current_var)) {
      environment_block += current_var_size;
      continue;
    }
    if (current_var[0] != '=')
      env.insert(current_var);

    environment_block += current_var_size;
  }
  return env;
}
