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

// C Includes
#include <stdio.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <execinfo.h>

// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Error.h"
#include "lldb/Target/Process.h"

#include "lldb/Host/Host.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"

#include "lldb/Core/ModuleSpec.h"
#include "lldb/Symbol/ObjectFile.h"

using namespace lldb;
using namespace lldb_private;

typedef enum ProcessStateFlags
{
    eProcessStateRunning           = (1u << 0), // Running
    eProcessStateSleeping          = (1u << 1), // Sleeping in an interruptible wait
    eProcessStateWaiting           = (1u << 2), // Waiting in an uninterruptible disk sleep
    eProcessStateZombie            = (1u << 3), // Zombie
    eProcessStateTracedOrStopped   = (1u << 4), // Traced or stopped (on a signal)
    eProcessStatePaging            = (1u << 5)  // Paging
} ProcessStateFlags;

typedef struct ProcessStatInfo
{
    lldb::pid_t ppid;           // Parent Process ID
    uint32_t fProcessState;     // ProcessStateFlags
} ProcessStatInfo;

// Get the process info with additional information from /proc/$PID/stat (like process state, and tracer pid).
static bool GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid);


namespace
{

lldb::DataBufferSP
ReadProcPseudoFile (lldb::pid_t pid, const char *name)
{
    int fd;
    char path[PATH_MAX];

    // Make sure we've got a nil terminated buffer for all the folks calling
    // GetBytes() directly off our returned DataBufferSP if we hit an error.
    lldb::DataBufferSP buf_sp (new DataBufferHeap(1, 0));

    // Ideally, we would simply create a FileSpec and call ReadFileContents.
    // However, files in procfs have zero size (since they are, in general,
    // dynamically generated by the kernel) which is incompatible with the
    // current ReadFileContents implementation. Therefore we simply stream the
    // data into a DataBuffer ourselves.
    if (snprintf (path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0)
    {
        if ((fd = open (path, O_RDONLY, 0)) >= 0)
        {
            size_t bytes_read = 0;
            std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));

            for (;;) 
            {
                size_t avail = buf_ap->GetByteSize() - bytes_read;
                ssize_t status = read (fd, buf_ap->GetBytes() + bytes_read, avail);

                if (status < 0) 
                    break;

                if (status == 0) 
                {
                    buf_ap->SetByteSize (bytes_read);
                    buf_sp.reset (buf_ap.release());
                    break;
                }

                bytes_read += status;

                if (avail - status == 0)
                    buf_ap->SetByteSize (2 * buf_ap->GetByteSize());
            }

            close (fd);
        }
    }

    return buf_sp;
}

lldb::DataBufferSP
ReadProcPseudoFile (lldb::pid_t pid, lldb::tid_t tid, const char *name)
{
    std::string process_thread_pseudo_file = "task/" + std::to_string(tid) + "/" + name;
    return ReadProcPseudoFile(pid, process_thread_pseudo_file.c_str());
}

} // anonymous namespace

static bool
ReadProcPseudoFileStat (lldb::pid_t pid, ProcessStatInfo& stat_info)
{
    // Read the /proc/$PID/stat file.
    lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, "stat");

    // The filename of the executable is stored in parenthesis right after the pid. We look for the closing
    // parenthesis for the filename and work from there in case the name has something funky like ')' in it.
    const char *filename_end = strrchr ((const char *)buf_sp->GetBytes(), ')');
    if (filename_end)
    {
        char state = '\0';
        int ppid = LLDB_INVALID_PROCESS_ID;

        // Read state and ppid.
        sscanf (filename_end + 1, " %c %d", &state, &ppid);

        stat_info.ppid = ppid;

        switch (state)
        {
            case 'R':
                stat_info.fProcessState |= eProcessStateRunning;
                break;
            case 'S':
                stat_info.fProcessState |= eProcessStateSleeping;
                break;
            case 'D':
                stat_info.fProcessState |= eProcessStateWaiting;
                break;
            case 'Z':
                stat_info.fProcessState |= eProcessStateZombie;
                break;
            case 'T':
                stat_info.fProcessState |= eProcessStateTracedOrStopped;
                break;
            case 'W':
                stat_info.fProcessState |= eProcessStatePaging;
                break;
        }

        return true;
    }

    return false;
}

static void
GetLinuxProcessUserAndGroup (lldb::pid_t pid, ProcessInstanceInfo &process_info, lldb::pid_t &tracerpid)
{
    tracerpid = 0;
    uint32_t rUid = UINT32_MAX;     // Real User ID
    uint32_t eUid = UINT32_MAX;     // Effective User ID
    uint32_t rGid = UINT32_MAX;     // Real Group ID
    uint32_t eGid = UINT32_MAX;     // Effective Group ID

    // Read the /proc/$PID/status file and parse the Uid:, Gid:, and TracerPid: fields.
    lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, "status");

    static const char uid_token[] = "Uid:";
    char *buf_uid = strstr ((char *)buf_sp->GetBytes(), uid_token);
    if (buf_uid)
    {
        // Real, effective, saved set, and file system UIDs. Read the first two.
        buf_uid += sizeof(uid_token);
        rUid = strtol (buf_uid, &buf_uid, 10);
        eUid = strtol (buf_uid, &buf_uid, 10);
    }

    static const char gid_token[] = "Gid:";
    char *buf_gid = strstr ((char *)buf_sp->GetBytes(), gid_token);
    if (buf_gid)
    {
        // Real, effective, saved set, and file system GIDs. Read the first two.
        buf_gid += sizeof(gid_token);
        rGid = strtol (buf_gid, &buf_gid, 10);
        eGid = strtol (buf_gid, &buf_gid, 10);
    }

    static const char tracerpid_token[] = "TracerPid:";
    char *buf_tracerpid = strstr((char *)buf_sp->GetBytes(), tracerpid_token);
    if (buf_tracerpid)
    {
        // Tracer PID. 0 if we're not being debugged.
        buf_tracerpid += sizeof(tracerpid_token);
        tracerpid = strtol (buf_tracerpid, &buf_tracerpid, 10);
    }

    process_info.SetUserID (rUid);
    process_info.SetEffectiveUserID (eUid);
    process_info.SetGroupID (rGid);
    process_info.SetEffectiveGroupID (eGid);
}

bool
Host::GetOSVersion(uint32_t &major,
                   uint32_t &minor,
                   uint32_t &update)
{
    struct utsname un;
    int status;

    if (uname(&un))
        return false;

    status = sscanf(un.release, "%u.%u.%u", &major, &minor, &update);
    return status == 3;
}

Error
Host::LaunchProcess (ProcessLaunchInfo &launch_info)
{
    Error error;
    assert(!"Not implemented yet!!!");
    return error;
}

lldb::DataBufferSP
Host::GetAuxvData(lldb_private::Process *process)
{
    return ReadProcPseudoFile(process->GetID(), "auxv");
}

static bool
IsDirNumeric(const char *dname)
{
    for (; *dname; dname++)
    {
        if (!isdigit (*dname))
            return false;
    }
    return true;
}

uint32_t
Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
{
    static const char procdir[] = "/proc/";

    DIR *dirproc = opendir (procdir);
    if (dirproc)
    {
        struct dirent *direntry = NULL;
        const uid_t our_uid = getuid();
        const lldb::pid_t our_pid = getpid();
        bool all_users = match_info.GetMatchAllUsers();

        while ((direntry = readdir (dirproc)) != NULL)
        {
            if (direntry->d_type != DT_DIR || !IsDirNumeric (direntry->d_name))
                continue;

            lldb::pid_t pid = atoi (direntry->d_name);

            // Skip this process.
            if (pid == our_pid)
                continue;

            lldb::pid_t tracerpid;
            ProcessStatInfo stat_info;
            ProcessInstanceInfo process_info;

            if (!GetProcessAndStatInfo (pid, process_info, stat_info, tracerpid))
                continue;

            // Skip if process is being debugged.
            if (tracerpid != 0)
                continue;

            // Skip zombies.
            if (stat_info.fProcessState & eProcessStateZombie)
                continue;

            // Check for user match if we're not matching all users and not running as root.
            if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
                continue;

            if (match_info.Matches (process_info))
            {
                process_infos.Append (process_info);
            }
        }

        closedir (dirproc);
    }

    return process_infos.GetSize();
}

bool
Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
{
    bool tids_changed = false;
    static const char procdir[] = "/proc/";
    static const char taskdir[] = "/task/";
    std::string process_task_dir = procdir + std::to_string(pid) + taskdir;
    DIR *dirproc = opendir (process_task_dir.c_str());

    if (dirproc)
    {
        struct dirent *direntry = NULL;
        while ((direntry = readdir (dirproc)) != NULL)
        {
            if (direntry->d_type != DT_DIR || !IsDirNumeric (direntry->d_name))
                continue;

            lldb::tid_t tid = atoi(direntry->d_name);
            TidMap::iterator it = tids_to_attach.find(tid);
            if (it == tids_to_attach.end())
            {
                tids_to_attach.insert(TidPair(tid, false));
                tids_changed = true;
            }
        }
        closedir (dirproc);
    }

    return tids_changed;
}

static bool
GetELFProcessCPUType (const char *exe_path, ProcessInstanceInfo &process_info)
{
    // Clear the architecture.
    process_info.GetArchitecture().Clear();

    ModuleSpecList specs;
    FileSpec filespec (exe_path, false);
    const size_t num_specs = ObjectFile::GetModuleSpecifications (filespec, 0, 0, specs);
    // GetModuleSpecifications() could fail if the executable has been deleted or is locked.
    // But it shouldn't return more than 1 architecture.
    assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
    if (num_specs == 1)
    {
        ModuleSpec module_spec;
        if (specs.GetModuleSpecAtIndex (0, module_spec) && module_spec.GetArchitecture().IsValid())
        {
            process_info.GetArchitecture () = module_spec.GetArchitecture();
            return true;
        }
    }
    return false;
}

static bool
GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid)
{
    tracerpid = 0;
    process_info.Clear();
    ::memset (&stat_info, 0, sizeof(stat_info));
    stat_info.ppid = LLDB_INVALID_PROCESS_ID;

    // Use special code here because proc/[pid]/exe is a symbolic link.
    char link_path[PATH_MAX];
    char exe_path[PATH_MAX] = "";
    if (snprintf (link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", pid) <= 0)
        return false;

    ssize_t len = readlink (link_path, exe_path, sizeof(exe_path) - 1);
    if (len <= 0)
        return false;

    // readlink does not append a null byte.
    exe_path[len] = 0;

    // If the binary has been deleted, the link name has " (deleted)" appended.
    //  Remove if there.
    static const ssize_t deleted_len = strlen(" (deleted)");
    if (len > deleted_len &&
        !strcmp(exe_path + len - deleted_len, " (deleted)"))
    {
        exe_path[len - deleted_len] = 0;
    }
    else
    {
        GetELFProcessCPUType (exe_path, process_info);
    }

    process_info.SetProcessID(pid);
    process_info.GetExecutableFile().SetFile(exe_path, false);

    lldb::DataBufferSP buf_sp;

    // Get the process environment.
    buf_sp = ReadProcPseudoFile(pid, "environ");
    Args &info_env = process_info.GetEnvironmentEntries();
    char *next_var = (char *)buf_sp->GetBytes();
    char *end_buf = next_var + buf_sp->GetByteSize();
    while (next_var < end_buf && 0 != *next_var)
    {
        info_env.AppendArgument(next_var);
        next_var += strlen(next_var) + 1;
    }

    // Get the commond line used to start the process.
    buf_sp = ReadProcPseudoFile(pid, "cmdline");

    // Grab Arg0 first.
    char *cmd = (char *)buf_sp->GetBytes();
    process_info.SetArg0(cmd);

    // Now process any remaining arguments.
    Args &info_args = process_info.GetArguments();
    char *next_arg = cmd + strlen(cmd) + 1;
    end_buf = cmd + buf_sp->GetByteSize();
    while (next_arg < end_buf && 0 != *next_arg)
    {
        info_args.AppendArgument(next_arg);
        next_arg += strlen(next_arg) + 1;
    }

    // Read /proc/$PID/stat to get our parent pid.
    if (ReadProcPseudoFileStat (pid, stat_info))
    {
        process_info.SetParentProcessID (stat_info.ppid);
    }

    // Get User and Group IDs and get tracer pid.
    GetLinuxProcessUserAndGroup (pid, process_info, tracerpid);

    return true;
}

bool
Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
{
    lldb::pid_t tracerpid;
    ProcessStatInfo stat_info;

    return GetProcessAndStatInfo (pid, process_info, stat_info, tracerpid);
}

void
Host::ThreadCreated (const char *thread_name)
{
    if (!Host::SetThreadName (LLDB_INVALID_PROCESS_ID, LLDB_INVALID_THREAD_ID, thread_name))
    {
        Host::SetShortThreadName (LLDB_INVALID_PROCESS_ID, LLDB_INVALID_THREAD_ID, thread_name, 16);
    }
}

std::string
Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
{
    const size_t thread_name_max_size = 16;
    char pthread_name[thread_name_max_size];
    std::string thread_name;
    // Read the /proc/$PID/stat file.
    lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, tid, "stat");

    // The file/thread name of the executable is stored in parenthesis. Search for the first
    // '(' and last ')' and copy everything in between.
    const char *filename_start = ::strchr ((const char *)buf_sp->GetBytes(), '(');
    const char *filename_end = ::strrchr ((const char *)buf_sp->GetBytes(), ')');

    if (filename_start && filename_end)
    {
        ++filename_start;
        size_t length = filename_end - filename_start;
        if (length > thread_name_max_size)
            length = thread_name_max_size;
        strncpy(pthread_name, filename_start, length);
        thread_name = std::string(pthread_name, length);
    }

    return thread_name;
}

void
Host::Backtrace (Stream &strm, uint32_t max_frames)
{
    if (max_frames > 0)
    {
        std::vector<void *> frame_buffer (max_frames, NULL);
        int num_frames = ::backtrace (&frame_buffer[0], frame_buffer.size());
        char** strs = ::backtrace_symbols (&frame_buffer[0], num_frames);
        if (strs)
        {
            // Start at 1 to skip the "Host::Backtrace" frame
            for (int i = 1; i < num_frames; ++i)
                strm.Printf("%s\n", strs[i]);
            ::free (strs);
        }
    }
}

size_t
Host::GetEnvironment (StringList &env)
{
    char **host_env = environ;
    char *env_entry;
    size_t i;
    for (i=0; (env_entry = host_env[i]) != NULL; ++i)
        env.AppendString(env_entry);
    return i;
}
