//===-- SBPlatform.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/API/SBPlatform.h"
#include "lldb/API/SBEnvironment.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBPlatform.h"
#include "lldb/API/SBUnixSignals.h"
#include "lldb/Host/File.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Instrumentation.h"
#include "lldb/Utility/Status.h"

#include "llvm/Support/FileSystem.h"

#include <functional>

using namespace lldb;
using namespace lldb_private;

// PlatformConnectOptions
struct PlatformConnectOptions {
  PlatformConnectOptions(const char *url = nullptr) {
    if (url && url[0])
      m_url = url;
  }

  ~PlatformConnectOptions() = default;

  std::string m_url;
  std::string m_rsync_options;
  std::string m_rsync_remote_path_prefix;
  bool m_rsync_enabled = false;
  bool m_rsync_omit_hostname_from_remote_path = false;
  ConstString m_local_cache_directory;
};

// PlatformShellCommand
struct PlatformShellCommand {
  PlatformShellCommand(llvm::StringRef shell_interpreter,
                       llvm::StringRef shell_command) {
    if (!shell_interpreter.empty())
      m_shell = shell_interpreter.str();

    if (!m_shell.empty() && !shell_command.empty())
      m_command = shell_command.str();
  }

  PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef()) {
    if (!shell_command.empty())
      m_command = shell_command.str();
  }

  ~PlatformShellCommand() = default;

  std::string m_shell;
  std::string m_command;
  std::string m_working_dir;
  std::string m_output;
  int m_status = 0;
  int m_signo = 0;
  Timeout<std::ratio<1>> m_timeout = std::nullopt;
};
// SBPlatformConnectOptions
SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
    : m_opaque_ptr(new PlatformConnectOptions(url)) {
  LLDB_INSTRUMENT_VA(this, url);
}

SBPlatformConnectOptions::SBPlatformConnectOptions(
    const SBPlatformConnectOptions &rhs)
    : m_opaque_ptr(new PlatformConnectOptions()) {
  LLDB_INSTRUMENT_VA(this, rhs);

  *m_opaque_ptr = *rhs.m_opaque_ptr;
}

SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }

SBPlatformConnectOptions &
SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  *m_opaque_ptr = *rhs.m_opaque_ptr;
  return *this;
}

const char *SBPlatformConnectOptions::GetURL() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr->m_url.empty())
    return nullptr;
  return m_opaque_ptr->m_url.c_str();
}

void SBPlatformConnectOptions::SetURL(const char *url) {
  LLDB_INSTRUMENT_VA(this, url);

  if (url && url[0])
    m_opaque_ptr->m_url = url;
  else
    m_opaque_ptr->m_url.clear();
}

bool SBPlatformConnectOptions::GetRsyncEnabled() {
  LLDB_INSTRUMENT_VA(this);

  return m_opaque_ptr->m_rsync_enabled;
}

void SBPlatformConnectOptions::EnableRsync(
    const char *options, const char *remote_path_prefix,
    bool omit_hostname_from_remote_path) {
  LLDB_INSTRUMENT_VA(this, options, remote_path_prefix,
                     omit_hostname_from_remote_path);

  m_opaque_ptr->m_rsync_enabled = true;
  m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =
      omit_hostname_from_remote_path;
  if (remote_path_prefix && remote_path_prefix[0])
    m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
  else
    m_opaque_ptr->m_rsync_remote_path_prefix.clear();

  if (options && options[0])
    m_opaque_ptr->m_rsync_options = options;
  else
    m_opaque_ptr->m_rsync_options.clear();
}

void SBPlatformConnectOptions::DisableRsync() {
  LLDB_INSTRUMENT_VA(this);

  m_opaque_ptr->m_rsync_enabled = false;
}

const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
  LLDB_INSTRUMENT_VA(this);

  return m_opaque_ptr->m_local_cache_directory.GetCString();
}

void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
  LLDB_INSTRUMENT_VA(this, path);

  if (path && path[0])
    m_opaque_ptr->m_local_cache_directory.SetCString(path);
  else
    m_opaque_ptr->m_local_cache_directory = ConstString();
}

// SBPlatformShellCommand
SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_interpreter,
                                               const char *shell_command)
    : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) {
  LLDB_INSTRUMENT_VA(this, shell_interpreter, shell_command);
}

SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
    : m_opaque_ptr(new PlatformShellCommand(shell_command)) {
  LLDB_INSTRUMENT_VA(this, shell_command);
}

SBPlatformShellCommand::SBPlatformShellCommand(
    const SBPlatformShellCommand &rhs)
    : m_opaque_ptr(new PlatformShellCommand()) {
  LLDB_INSTRUMENT_VA(this, rhs);

  *m_opaque_ptr = *rhs.m_opaque_ptr;
}

SBPlatformShellCommand &
SBPlatformShellCommand::operator=(const SBPlatformShellCommand &rhs) {

  LLDB_INSTRUMENT_VA(this, rhs);

  *m_opaque_ptr = *rhs.m_opaque_ptr;
  return *this;
}

SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }

void SBPlatformShellCommand::Clear() {
  LLDB_INSTRUMENT_VA(this);

  m_opaque_ptr->m_output = std::string();
  m_opaque_ptr->m_status = 0;
  m_opaque_ptr->m_signo = 0;
}

const char *SBPlatformShellCommand::GetShell() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr->m_shell.empty())
    return nullptr;
  return m_opaque_ptr->m_shell.c_str();
}

void SBPlatformShellCommand::SetShell(const char *shell_interpreter) {
  LLDB_INSTRUMENT_VA(this, shell_interpreter);

  if (shell_interpreter && shell_interpreter[0])
    m_opaque_ptr->m_shell = shell_interpreter;
  else
    m_opaque_ptr->m_shell.clear();
}

const char *SBPlatformShellCommand::GetCommand() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr->m_command.empty())
    return nullptr;
  return m_opaque_ptr->m_command.c_str();
}

void SBPlatformShellCommand::SetCommand(const char *shell_command) {
  LLDB_INSTRUMENT_VA(this, shell_command);

  if (shell_command && shell_command[0])
    m_opaque_ptr->m_command = shell_command;
  else
    m_opaque_ptr->m_command.clear();
}

const char *SBPlatformShellCommand::GetWorkingDirectory() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr->m_working_dir.empty())
    return nullptr;
  return m_opaque_ptr->m_working_dir.c_str();
}

void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
  LLDB_INSTRUMENT_VA(this, path);

  if (path && path[0])
    m_opaque_ptr->m_working_dir = path;
  else
    m_opaque_ptr->m_working_dir.clear();
}

uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr->m_timeout)
    return m_opaque_ptr->m_timeout->count();
  return UINT32_MAX;
}

void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
  LLDB_INSTRUMENT_VA(this, sec);

  if (sec == UINT32_MAX)
    m_opaque_ptr->m_timeout = std::nullopt;
  else
    m_opaque_ptr->m_timeout = std::chrono::seconds(sec);
}

int SBPlatformShellCommand::GetSignal() {
  LLDB_INSTRUMENT_VA(this);

  return m_opaque_ptr->m_signo;
}

int SBPlatformShellCommand::GetStatus() {
  LLDB_INSTRUMENT_VA(this);

  return m_opaque_ptr->m_status;
}

const char *SBPlatformShellCommand::GetOutput() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr->m_output.empty())
    return nullptr;
  return m_opaque_ptr->m_output.c_str();
}

// SBPlatform
SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); }

SBPlatform::SBPlatform(const char *platform_name) {
  LLDB_INSTRUMENT_VA(this, platform_name);

  m_opaque_sp = Platform::Create(platform_name);
}

SBPlatform::SBPlatform(const SBPlatform &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  m_opaque_sp = rhs.m_opaque_sp;
}

SBPlatform &SBPlatform::operator=(const SBPlatform &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  m_opaque_sp = rhs.m_opaque_sp;
  return *this;
}

SBPlatform::~SBPlatform() = default;

SBPlatform SBPlatform::GetHostPlatform() {
  LLDB_INSTRUMENT();

  SBPlatform host_platform;
  host_platform.m_opaque_sp = Platform::GetHostPlatform();
  return host_platform;
}

bool SBPlatform::IsValid() const {
  LLDB_INSTRUMENT_VA(this);
  return this->operator bool();
}
SBPlatform::operator bool() const {
  LLDB_INSTRUMENT_VA(this);

  return m_opaque_sp.get() != nullptr;
}

void SBPlatform::Clear() {
  LLDB_INSTRUMENT_VA(this);

  m_opaque_sp.reset();
}

const char *SBPlatform::GetName() {
  LLDB_INSTRUMENT_VA(this);

  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    return ConstString(platform_sp->GetName()).AsCString();
  return nullptr;
}

lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }

void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
  m_opaque_sp = platform_sp;
}

const char *SBPlatform::GetWorkingDirectory() {
  LLDB_INSTRUMENT_VA(this);

  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    return platform_sp->GetWorkingDirectory().GetPathAsConstString().AsCString();
  return nullptr;
}

bool SBPlatform::SetWorkingDirectory(const char *path) {
  LLDB_INSTRUMENT_VA(this, path);

  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    if (path)
      platform_sp->SetWorkingDirectory(FileSpec(path));
    else
      platform_sp->SetWorkingDirectory(FileSpec());
    return true;
  }
  return false;
}

SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
  LLDB_INSTRUMENT_VA(this, connect_options);

  SBError sb_error;
  PlatformSP platform_sp(GetSP());
  if (platform_sp && connect_options.GetURL()) {
    Args args;
    args.AppendArgument(connect_options.GetURL());
    sb_error.ref() = platform_sp->ConnectRemote(args);
  } else {
    sb_error.SetErrorString("invalid platform");
  }
  return sb_error;
}

void SBPlatform::DisconnectRemote() {
  LLDB_INSTRUMENT_VA(this);

  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    platform_sp->DisconnectRemote();
}

bool SBPlatform::IsConnected() {
  LLDB_INSTRUMENT_VA(this);

  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    return platform_sp->IsConnected();
  return false;
}

const char *SBPlatform::GetTriple() {
  LLDB_INSTRUMENT_VA(this);

  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    ArchSpec arch(platform_sp->GetSystemArchitecture());
    if (arch.IsValid()) {
      // Const-ify the string so we don't need to worry about the lifetime of
      // the string
      return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
    }
  }
  return nullptr;
}

const char *SBPlatform::GetOSBuild() {
  LLDB_INSTRUMENT_VA(this);

  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    std::string s = platform_sp->GetOSBuildString().value_or("");
    if (!s.empty()) {
      // Const-ify the string so we don't need to worry about the lifetime of
      // the string
      return ConstString(s).GetCString();
    }
  }
  return nullptr;
}

const char *SBPlatform::GetOSDescription() {
  LLDB_INSTRUMENT_VA(this);

  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    std::string s = platform_sp->GetOSKernelDescription().value_or("");
    if (!s.empty()) {
      // Const-ify the string so we don't need to worry about the lifetime of
      // the string
      return ConstString(s.c_str()).GetCString();
    }
  }
  return nullptr;
}

const char *SBPlatform::GetHostname() {
  LLDB_INSTRUMENT_VA(this);

  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    return platform_sp->GetHostname();
  return nullptr;
}

uint32_t SBPlatform::GetOSMajorVersion() {
  LLDB_INSTRUMENT_VA(this);

  llvm::VersionTuple version;
  if (PlatformSP platform_sp = GetSP())
    version = platform_sp->GetOSVersion();
  return version.empty() ? UINT32_MAX : version.getMajor();
}

uint32_t SBPlatform::GetOSMinorVersion() {
  LLDB_INSTRUMENT_VA(this);

  llvm::VersionTuple version;
  if (PlatformSP platform_sp = GetSP())
    version = platform_sp->GetOSVersion();
  return version.getMinor().value_or(UINT32_MAX);
}

uint32_t SBPlatform::GetOSUpdateVersion() {
  LLDB_INSTRUMENT_VA(this);

  llvm::VersionTuple version;
  if (PlatformSP platform_sp = GetSP())
    version = platform_sp->GetOSVersion();
  return version.getSubminor().value_or(UINT32_MAX);
}

void SBPlatform::SetSDKRoot(const char *sysroot) {
  LLDB_INSTRUMENT_VA(this, sysroot);
  if (PlatformSP platform_sp = GetSP())
    platform_sp->SetSDKRootDirectory(ConstString(sysroot));
}

SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
  LLDB_INSTRUMENT_VA(this, src, dst);

  SBError sb_error;
  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
  } else {
    sb_error.SetErrorString("invalid platform");
  }
  return sb_error;
}

SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
  LLDB_INSTRUMENT_VA(this, src, dst);
  return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
    if (src.Exists()) {
      uint32_t permissions = FileSystem::Instance().GetPermissions(src.ref());
      if (permissions == 0) {
        if (FileSystem::Instance().IsDirectory(src.ref()))
          permissions = eFilePermissionsDirectoryDefault;
        else
          permissions = eFilePermissionsFileDefault;
      }

      return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
    }

    Status error;
    error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
                                   src.ref().GetPath().c_str());
    return error;
  });
}

SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
  LLDB_INSTRUMENT_VA(this, src, dst);
  return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
    if (src.Exists())
      return platform_sp->Install(src.ref(), dst.ref());

    Status error;
    error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
                                   src.ref().GetPath().c_str());
    return error;
  });
}

SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
  LLDB_INSTRUMENT_VA(this, shell_command);
  return ExecuteConnected(
      [&](const lldb::PlatformSP &platform_sp) {
        const char *command = shell_command.GetCommand();
        if (!command)
          return Status("invalid shell command (empty)");

        if (shell_command.GetWorkingDirectory() == nullptr) {
          std::string platform_working_dir =
              platform_sp->GetWorkingDirectory().GetPath();
          if (!platform_working_dir.empty())
            shell_command.SetWorkingDirectory(platform_working_dir.c_str());
        }
        return platform_sp->RunShellCommand(
            shell_command.m_opaque_ptr->m_shell, command,
            FileSpec(shell_command.GetWorkingDirectory()),
            &shell_command.m_opaque_ptr->m_status,
            &shell_command.m_opaque_ptr->m_signo,
            &shell_command.m_opaque_ptr->m_output,
            shell_command.m_opaque_ptr->m_timeout);
      });
}

SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
  LLDB_INSTRUMENT_VA(this, launch_info);
  return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
    ProcessLaunchInfo info = launch_info.ref();
    Status error = platform_sp->LaunchProcess(info);
    launch_info.set_ref(info);
    return error;
  });
}

SBError SBPlatform::Kill(const lldb::pid_t pid) {
  LLDB_INSTRUMENT_VA(this, pid);
  return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
    return platform_sp->KillProcess(pid);
  });
}

SBError SBPlatform::ExecuteConnected(
    const std::function<Status(const lldb::PlatformSP &)> &func) {
  SBError sb_error;
  const auto platform_sp(GetSP());
  if (platform_sp) {
    if (platform_sp->IsConnected())
      sb_error.ref() = func(platform_sp);
    else
      sb_error.SetErrorString("not connected");
  } else
    sb_error.SetErrorString("invalid platform");

  return sb_error;
}

SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
  LLDB_INSTRUMENT_VA(this, path, file_permissions);

  SBError sb_error;
  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    sb_error.ref() =
        platform_sp->MakeDirectory(FileSpec(path), file_permissions);
  } else {
    sb_error.SetErrorString("invalid platform");
  }
  return sb_error;
}

uint32_t SBPlatform::GetFilePermissions(const char *path) {
  LLDB_INSTRUMENT_VA(this, path);

  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    uint32_t file_permissions = 0;
    platform_sp->GetFilePermissions(FileSpec(path), file_permissions);
    return file_permissions;
  }
  return 0;
}

SBError SBPlatform::SetFilePermissions(const char *path,
                                       uint32_t file_permissions) {
  LLDB_INSTRUMENT_VA(this, path, file_permissions);

  SBError sb_error;
  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    sb_error.ref() =
        platform_sp->SetFilePermissions(FileSpec(path), file_permissions);
  } else {
    sb_error.SetErrorString("invalid platform");
  }
  return sb_error;
}

SBUnixSignals SBPlatform::GetUnixSignals() const {
  LLDB_INSTRUMENT_VA(this);

  if (auto platform_sp = GetSP())
    return SBUnixSignals{platform_sp};

  return SBUnixSignals();
}

SBEnvironment SBPlatform::GetEnvironment() {
  LLDB_INSTRUMENT_VA(this);
  PlatformSP platform_sp(GetSP());

  if (platform_sp) {
    return SBEnvironment(platform_sp->GetEnvironment());
  }

  return SBEnvironment();
}
