//===-- 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/Core/ArchSpec.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/File.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Platform.h"

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::move(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(ConstString(path));
        else
            platform_sp->SetWorkingDirectory(ConstString());
        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(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->GetRemoteSystemArchitecture());
        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)
{
    SBError sb_error;
    
    PlatformSP platform_sp(GetSP());
    if (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;
            }

            sb_error.ref() = platform_sp->PutFile(src.ref(),
                                                  dst.ref(),
                                                  permissions);
        }
        else
        {
            sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
        }
    }
    else
    {
        sb_error.SetErrorString("invalid platform");
    }
    return sb_error;
}

SBError
SBPlatform::Install (SBFileSpec &src,
                     SBFileSpec &dst)
{
    SBError sb_error;
    PlatformSP platform_sp(GetSP());
    if (platform_sp)
    {
        if (src.Exists())
        {
            sb_error.ref() = platform_sp->Install(src.ref(), dst.ref());
        }
        else
        {
            sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
        }
    }
    else
    {
        sb_error.SetErrorString("invalid platform");
    }
    return sb_error;
}


SBError
SBPlatform::Run (SBPlatformShellCommand &shell_command)
{
    SBError sb_error;
    PlatformSP platform_sp(GetSP());
    if (platform_sp)
    {
        if (platform_sp->IsConnected())
        {
            const char *command = shell_command.GetCommand();
            if (command)
            {
                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);
                }
                sb_error.ref() = platform_sp->RunShellCommand(command,
                                                              working_dir,
                                                              &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);
            }
            else
            {
                sb_error.SetErrorString("invalid shell command (empty)");
            }
        }
        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(path, 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(path, 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(path, file_permissions);
    }
    else
    {
        sb_error.SetErrorString("invalid platform");
    }
    return sb_error;
    
}

