//===-- SBPlatform.cpp ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBPlatform.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBLaunchInfo.h"
#include "lldb/API/SBUnixSignals.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/File.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Target.h"

#include <functional>

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// PlatformConnectOptions
//----------------------------------------------------------------------
struct PlatformConnectOptions {
  PlatformConnectOptions(const char *url = NULL)
      : m_url(), m_rsync_options(), m_rsync_remote_path_prefix(),
        m_rsync_enabled(false), m_rsync_omit_hostname_from_remote_path(false),
        m_local_cache_directory() {
    if (url && url[0])
      m_url = url;
  }

  ~PlatformConnectOptions() {}

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

//----------------------------------------------------------------------
// PlatformShellCommand
//----------------------------------------------------------------------
struct PlatformShellCommand {
  PlatformShellCommand(const char *shell_command = NULL)
      : m_command(), m_working_dir(), m_status(0), m_signo(0),
        m_timeout_sec(UINT32_MAX) {
    if (shell_command && shell_command[0])
      m_command = shell_command;
  }

  ~PlatformShellCommand() {}

  std::string m_command;
  std::string m_working_dir;
  std::string m_output;
  int m_status;
  int m_signo;
  uint32_t m_timeout_sec;
};
//----------------------------------------------------------------------
// SBPlatformConnectOptions
//----------------------------------------------------------------------
SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
    : m_opaque_ptr(new PlatformConnectOptions(url)) {}

SBPlatformConnectOptions::SBPlatformConnectOptions(
    const SBPlatformConnectOptions &rhs)
    : m_opaque_ptr(new PlatformConnectOptions()) {
  *m_opaque_ptr = *rhs.m_opaque_ptr;
}

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

void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
  *m_opaque_ptr = *rhs.m_opaque_ptr;
}

const char *SBPlatformConnectOptions::GetURL() {
  if (m_opaque_ptr->m_url.empty())
    return NULL;
  return m_opaque_ptr->m_url.c_str();
}

void SBPlatformConnectOptions::SetURL(const char *url) {
  if (url && url[0])
    m_opaque_ptr->m_url = url;
  else
    m_opaque_ptr->m_url.clear();
}

bool SBPlatformConnectOptions::GetRsyncEnabled() {
  return m_opaque_ptr->m_rsync_enabled;
}

void SBPlatformConnectOptions::EnableRsync(
    const char *options, const char *remote_path_prefix,
    bool 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() {
  m_opaque_ptr->m_rsync_enabled = false;
}

const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
  return m_opaque_ptr->m_local_cache_directory.GetCString();
}

void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *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_command)
    : m_opaque_ptr(new PlatformShellCommand(shell_command)) {}

SBPlatformShellCommand::SBPlatformShellCommand(
    const SBPlatformShellCommand &rhs)
    : m_opaque_ptr(new PlatformShellCommand()) {
  *m_opaque_ptr = *rhs.m_opaque_ptr;
}

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

void SBPlatformShellCommand::Clear() {
  m_opaque_ptr->m_output = std::string();
  m_opaque_ptr->m_status = 0;
  m_opaque_ptr->m_signo = 0;
}

const char *SBPlatformShellCommand::GetCommand() {
  if (m_opaque_ptr->m_command.empty())
    return NULL;
  return m_opaque_ptr->m_command.c_str();
}

void SBPlatformShellCommand::SetCommand(const char *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() {
  if (m_opaque_ptr->m_working_dir.empty())
    return NULL;
  return m_opaque_ptr->m_working_dir.c_str();
}

void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
  if (path && path[0])
    m_opaque_ptr->m_working_dir = path;
  else
    m_opaque_ptr->m_working_dir.clear();
}

uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
  return m_opaque_ptr->m_timeout_sec;
}

void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
  m_opaque_ptr->m_timeout_sec = sec;
}

int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }

int SBPlatformShellCommand::GetStatus() { return m_opaque_ptr->m_status; }

const char *SBPlatformShellCommand::GetOutput() {
  if (m_opaque_ptr->m_output.empty())
    return NULL;
  return m_opaque_ptr->m_output.c_str();
}

//----------------------------------------------------------------------
// SBPlatform
//----------------------------------------------------------------------
SBPlatform::SBPlatform() : m_opaque_sp() {}

SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
  Error error;
  if (platform_name && platform_name[0])
    m_opaque_sp = Platform::Create(ConstString(platform_name), error);
}

SBPlatform::~SBPlatform() {}

bool SBPlatform::IsValid() const { return m_opaque_sp.get() != NULL; }

void SBPlatform::Clear() { m_opaque_sp.reset(); }

const char *SBPlatform::GetName() {
  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    return platform_sp->GetName().GetCString();
  return NULL;
}

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() {
  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    return platform_sp->GetWorkingDirectory().GetCString();
  return NULL;
}

bool SBPlatform::SetWorkingDirectory(const char *path) {
  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    if (path)
      platform_sp->SetWorkingDirectory(FileSpec{path, false});
    else
      platform_sp->SetWorkingDirectory(FileSpec{});
    return true;
  }
  return false;
}

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

void SBPlatform::DisconnectRemote() {
  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    platform_sp->DisconnectRemote();
}

bool SBPlatform::IsConnected() {
  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    platform_sp->IsConnected();
  return false;
}

const char *SBPlatform::GetTriple() {
  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 NULL;
}

const char *SBPlatform::GetOSBuild() {
  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    std::string s;
    if (platform_sp->GetOSBuildString(s)) {
      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 NULL;
}

const char *SBPlatform::GetOSDescription() {
  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    std::string s;
    if (platform_sp->GetOSKernelDescription(s)) {
      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 NULL;
}

const char *SBPlatform::GetHostname() {
  PlatformSP platform_sp(GetSP());
  if (platform_sp)
    return platform_sp->GetHostname();
  return NULL;
}

uint32_t SBPlatform::GetOSMajorVersion() {
  uint32_t major, minor, update;
  PlatformSP platform_sp(GetSP());
  if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
    return major;
  return UINT32_MAX;
}

uint32_t SBPlatform::GetOSMinorVersion() {
  uint32_t major, minor, update;
  PlatformSP platform_sp(GetSP());
  if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
    return minor;
  return UINT32_MAX;
}

uint32_t SBPlatform::GetOSUpdateVersion() {
  uint32_t major, minor, update;
  PlatformSP platform_sp(GetSP());
  if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
    return update;
  return UINT32_MAX;
}

SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &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) {
  return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
    if (src.Exists()) {
      uint32_t permissions = src.ref().GetPermissions();
      if (permissions == 0) {
        if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
          permissions = eFilePermissionsDirectoryDefault;
        else
          permissions = eFilePermissionsFileDefault;
      }

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

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

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

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

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

    const char *working_dir = shell_command.GetWorkingDirectory();
    if (working_dir == NULL) {
      working_dir = platform_sp->GetWorkingDirectory().GetCString();
      if (working_dir)
        shell_command.SetWorkingDirectory(working_dir);
    }
    return platform_sp->RunShellCommand(
        command, FileSpec{working_dir, false},
        &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_sec);
  });
}

SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
  return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
    return platform_sp->LaunchProcess(launch_info.ref());
  });
}

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

SBError SBPlatform::ExecuteConnected(
    const std::function<Error(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) {
  SBError sb_error;
  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    sb_error.ref() =
        platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
  } else {
    sb_error.SetErrorString("invalid platform");
  }
  return sb_error;
}

uint32_t SBPlatform::GetFilePermissions(const char *path) {
  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    uint32_t file_permissions = 0;
    platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
    return file_permissions;
  }
  return 0;
}

SBError SBPlatform::SetFilePermissions(const char *path,
                                       uint32_t file_permissions) {
  SBError sb_error;
  PlatformSP platform_sp(GetSP());
  if (platform_sp) {
    sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false},
                                                     file_permissions);
  } else {
    sb_error.SetErrorString("invalid platform");
  }
  return sb_error;
}

SBUnixSignals SBPlatform::GetUnixSignals() const {
  if (auto platform_sp = GetSP())
    return SBUnixSignals{platform_sp};

  return {};
}
