//===-- RemoteAwarePlatform.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/Target/RemoteAwarePlatform.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/FileCache.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb_private;
using namespace lldb;

bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec,
                                        const ArchSpec &arch,
                                        ModuleSpec &module_spec) {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
                                               module_spec);

  return false;
}

Status RemoteAwarePlatform::ResolveExecutable(
    const ModuleSpec &module_spec, ModuleSP &exe_module_sp,
    const FileSpecList *module_search_paths_ptr) {
  Status error;
  // Nothing special to do here, just use the actual file and architecture

  char exe_path[PATH_MAX];
  ModuleSpec resolved_module_spec(module_spec);

  if (IsHost()) {
    // If we have "ls" as the exe_file, resolve the executable location based
    // on the current path variables
    if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
      resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
      resolved_module_spec.GetFileSpec().SetFile(exe_path,
                                                 FileSpec::Style::native);
      FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec());
    }

    if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
      FileSystem::Instance().ResolveExecutableLocation(
          resolved_module_spec.GetFileSpec());

    // Resolve any executable within a bundle on MacOSX
    Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());

    if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
      error.Clear();
    else {
      const uint32_t permissions = FileSystem::Instance().GetPermissions(
          resolved_module_spec.GetFileSpec());
      if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
        error.SetErrorStringWithFormat(
            "executable '%s' is not readable",
            resolved_module_spec.GetFileSpec().GetPath().c_str());
      else
        error.SetErrorStringWithFormat(
            "unable to find executable for '%s'",
            resolved_module_spec.GetFileSpec().GetPath().c_str());
    }
  } else {
    if (m_remote_platform_sp) {
      return GetCachedExecutable(resolved_module_spec, exe_module_sp,
                                 module_search_paths_ptr);
    }

    // We may connect to a process and use the provided executable (Don't use
    // local $PATH).

    // Resolve any executable within a bundle on MacOSX
    Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());

    if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
      error.Clear();
    else
      error.SetErrorStringWithFormat("the platform is not currently "
                                     "connected, and '%s' doesn't exist in "
                                     "the system root.",
                                     exe_path);
  }

  if (error.Success()) {
    if (resolved_module_spec.GetArchitecture().IsValid()) {
      error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
                                          module_search_paths_ptr, nullptr, nullptr);
      if (error.Fail()) {
        // If we failed, it may be because the vendor and os aren't known. If
	// that is the case, try setting them to the host architecture and give
	// it another try.
        llvm::Triple &module_triple =
            resolved_module_spec.GetArchitecture().GetTriple();
        bool is_vendor_specified =
            (module_triple.getVendor() != llvm::Triple::UnknownVendor);
        bool is_os_specified =
            (module_triple.getOS() != llvm::Triple::UnknownOS);
        if (!is_vendor_specified || !is_os_specified) {
          const llvm::Triple &host_triple =
              HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();

          if (!is_vendor_specified)
            module_triple.setVendorName(host_triple.getVendorName());
          if (!is_os_specified)
            module_triple.setOSName(host_triple.getOSName());

          error = ModuleList::GetSharedModule(resolved_module_spec,
                                              exe_module_sp, module_search_paths_ptr, nullptr, nullptr);
        }
      }

      // TODO find out why exe_module_sp might be NULL
      if (error.Fail() || !exe_module_sp || !exe_module_sp->GetObjectFile()) {
        exe_module_sp.reset();
        error.SetErrorStringWithFormat(
            "'%s' doesn't contain the architecture %s",
            resolved_module_spec.GetFileSpec().GetPath().c_str(),
            resolved_module_spec.GetArchitecture().GetArchitectureName());
      }
    } else {
      // No valid architecture was specified, ask the platform for the
      // architectures that we should be using (in the correct order) and see
      // if we can find a match that way
      StreamString arch_names;
      llvm::ListSeparator LS;
      for (const ArchSpec &arch : GetSupportedArchitectures()) {
        resolved_module_spec.GetArchitecture() = arch;
        error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
                                            module_search_paths_ptr, nullptr, nullptr);
        // Did we find an executable using one of the
        if (error.Success()) {
          if (exe_module_sp && exe_module_sp->GetObjectFile())
            break;
          else
            error.SetErrorToGenericError();
        }

        arch_names << LS << arch.GetArchitectureName();
      }

      if (error.Fail() || !exe_module_sp) {
        if (FileSystem::Instance().Readable(
                resolved_module_spec.GetFileSpec())) {
          error.SetErrorStringWithFormatv(
              "'{0}' doesn't contain any '{1}' platform architectures: {2}",
              resolved_module_spec.GetFileSpec(), GetPluginName(),
              arch_names.GetData());
        } else {
          error.SetErrorStringWithFormat(
              "'%s' is not readable",
              resolved_module_spec.GetFileSpec().GetPath().c_str());
        }
      }
    }
  }

  return error;
}

Status RemoteAwarePlatform::RunShellCommand(
    llvm::StringRef command, const FileSpec &working_dir, int *status_ptr,
    int *signo_ptr, std::string *command_output,
    const Timeout<std::micro> &timeout) {
  return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr,
                         signo_ptr, command_output, timeout);
}

Status RemoteAwarePlatform::RunShellCommand(
    llvm::StringRef shell, llvm::StringRef command, const FileSpec &working_dir,
    int *status_ptr, int *signo_ptr, std::string *command_output,
    const Timeout<std::micro> &timeout) {
  if (IsHost())
    return Host::RunShellCommand(shell, command, working_dir, status_ptr,
                                 signo_ptr, command_output, timeout);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->RunShellCommand(shell, command, working_dir,
                                                 status_ptr, signo_ptr,
                                                 command_output, timeout);
  return Status("unable to run a remote command without a platform");
}

Status RemoteAwarePlatform::MakeDirectory(const FileSpec &file_spec,
                                          uint32_t file_permissions) {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions);
  return Platform::MakeDirectory(file_spec, file_permissions);
}

Status RemoteAwarePlatform::GetFilePermissions(const FileSpec &file_spec,
                                               uint32_t &file_permissions) {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetFilePermissions(file_spec,
                                                    file_permissions);
  return Platform::GetFilePermissions(file_spec, file_permissions);
}

Status RemoteAwarePlatform::SetFilePermissions(const FileSpec &file_spec,
                                               uint32_t file_permissions) {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->SetFilePermissions(file_spec,
                                                    file_permissions);
  return Platform::SetFilePermissions(file_spec, file_permissions);
}

lldb::user_id_t RemoteAwarePlatform::OpenFile(const FileSpec &file_spec,
                                              File::OpenOptions flags,
                                              uint32_t mode, Status &error) {
  if (IsHost())
    return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error);
  return Platform::OpenFile(file_spec, flags, mode, error);
}

bool RemoteAwarePlatform::CloseFile(lldb::user_id_t fd, Status &error) {
  if (IsHost())
    return FileCache::GetInstance().CloseFile(fd, error);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->CloseFile(fd, error);
  return Platform::CloseFile(fd, error);
}

uint64_t RemoteAwarePlatform::ReadFile(lldb::user_id_t fd, uint64_t offset,
                                       void *dst, uint64_t dst_len,
                                       Status &error) {
  if (IsHost())
    return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error);
  return Platform::ReadFile(fd, offset, dst, dst_len, error);
}

uint64_t RemoteAwarePlatform::WriteFile(lldb::user_id_t fd, uint64_t offset,
                                        const void *src, uint64_t src_len,
                                        Status &error) {
  if (IsHost())
    return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error);
  return Platform::WriteFile(fd, offset, src, src_len, error);
}

lldb::user_id_t RemoteAwarePlatform::GetFileSize(const FileSpec &file_spec) {
  if (IsHost()) {
    uint64_t Size;
    if (llvm::sys::fs::file_size(file_spec.GetPath(), Size))
      return 0;
    return Size;
  }
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetFileSize(file_spec);
  return Platform::GetFileSize(file_spec);
}

Status RemoteAwarePlatform::CreateSymlink(const FileSpec &src,
                                          const FileSpec &dst) {
  if (IsHost())
    return FileSystem::Instance().Symlink(src, dst);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->CreateSymlink(src, dst);
  return Platform::CreateSymlink(src, dst);
}

bool RemoteAwarePlatform::GetFileExists(const FileSpec &file_spec) {
  if (IsHost())
    return FileSystem::Instance().Exists(file_spec);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetFileExists(file_spec);
  return Platform::GetFileExists(file_spec);
}

Status RemoteAwarePlatform::Unlink(const FileSpec &file_spec) {
  if (IsHost())
    return llvm::sys::fs::remove(file_spec.GetPath());
  if (m_remote_platform_sp)
    return m_remote_platform_sp->Unlink(file_spec);
  return Platform::Unlink(file_spec);
}

bool RemoteAwarePlatform::CalculateMD5(const FileSpec &file_spec, uint64_t &low,
                                       uint64_t &high) {
  if (IsHost())
    return Platform::CalculateMD5(file_spec, low, high);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->CalculateMD5(file_spec, low, high);
  return false;
}

FileSpec RemoteAwarePlatform::GetRemoteWorkingDirectory() {
  if (IsRemote() && m_remote_platform_sp)
    return m_remote_platform_sp->GetRemoteWorkingDirectory();
  return Platform::GetRemoteWorkingDirectory();
}

bool RemoteAwarePlatform::SetRemoteWorkingDirectory(
    const FileSpec &working_dir) {
  if (IsRemote() && m_remote_platform_sp)
    return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir);
  return Platform::SetRemoteWorkingDirectory(working_dir);
}

Status RemoteAwarePlatform::GetFileWithUUID(const FileSpec &platform_file,
                                            const UUID *uuid_ptr,
                                            FileSpec &local_file) {
  if (IsRemote() && m_remote_platform_sp)
    return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
                                                 local_file);

  // Default to the local case
  local_file = platform_file;
  return Status();
}

bool RemoteAwarePlatform::GetRemoteOSVersion() {
  if (m_remote_platform_sp) {
    m_os_version = m_remote_platform_sp->GetOSVersion();
    return !m_os_version.empty();
  }
  return false;
}

llvm::Optional<std::string> RemoteAwarePlatform::GetRemoteOSBuildString() {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetRemoteOSBuildString();
  return llvm::None;
}

llvm::Optional<std::string> RemoteAwarePlatform::GetRemoteOSKernelDescription() {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetRemoteOSKernelDescription();
  return llvm::None;
}

ArchSpec RemoteAwarePlatform::GetRemoteSystemArchitecture() {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetRemoteSystemArchitecture();
  return ArchSpec();
}

const char *RemoteAwarePlatform::GetHostname() {
  if (IsHost())
    return Platform::GetHostname();
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetHostname();
  return nullptr;
}

UserIDResolver &RemoteAwarePlatform::GetUserIDResolver() {
  if (IsHost())
    return HostInfo::GetUserIDResolver();
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetUserIDResolver();
  return UserIDResolver::GetNoopResolver();
}

Environment RemoteAwarePlatform::GetEnvironment() {
  if (IsRemote()) {
    if (m_remote_platform_sp)
      return m_remote_platform_sp->GetEnvironment();
    return Environment();
  }
  return Host::GetEnvironment();
}

bool RemoteAwarePlatform::IsConnected() const {
  if (IsHost())
    return true;
  else if (m_remote_platform_sp)
    return m_remote_platform_sp->IsConnected();
  return false;
}

bool RemoteAwarePlatform::GetProcessInfo(lldb::pid_t pid,
                                         ProcessInstanceInfo &process_info) {
  if (IsHost())
    return Platform::GetProcessInfo(pid, process_info);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->GetProcessInfo(pid, process_info);
  return false;
}

uint32_t
RemoteAwarePlatform::FindProcesses(const ProcessInstanceInfoMatch &match_info,
                                   ProcessInstanceInfoList &process_infos) {
  if (IsHost())
    return Platform::FindProcesses(match_info, process_infos);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->FindProcesses(match_info, process_infos);
  return 0;
}

lldb::ProcessSP RemoteAwarePlatform::ConnectProcess(llvm::StringRef connect_url,
                                                    llvm::StringRef plugin_name,
                                                    Debugger &debugger,
                                                    Target *target,
                                                    Status &error) {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->ConnectProcess(connect_url, plugin_name,
                                                debugger, target, error);
  return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
                                  error);
}

Status RemoteAwarePlatform::LaunchProcess(ProcessLaunchInfo &launch_info) {
  Status error;

  if (IsHost()) {
    error = Platform::LaunchProcess(launch_info);
  } else {
    if (m_remote_platform_sp)
      error = m_remote_platform_sp->LaunchProcess(launch_info);
    else
      error.SetErrorString("the platform is not currently connected");
  }
  return error;
}

Status RemoteAwarePlatform::KillProcess(const lldb::pid_t pid) {
  if (IsHost())
    return Platform::KillProcess(pid);
  if (m_remote_platform_sp)
    return m_remote_platform_sp->KillProcess(pid);
  return Status("the platform is not currently connected");
}

size_t RemoteAwarePlatform::ConnectToWaitingProcesses(Debugger &debugger,
                                                Status &error) {
  if (m_remote_platform_sp)
    return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
  return Platform::ConnectToWaitingProcesses(debugger, error);
}
