//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_libc_calls
#endif

// system_utils_posix.cpp: Implementation of POSIX OS-specific functions.

#include "common/debug.h"
#include "system_utils.h"

#include <array>
#include <iostream>

#include <dlfcn.h>
#include <grp.h>
#include <inttypes.h>
#include <pwd.h>
#include <signal.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "common/string_utils.h"

#ifdef ANGLE_PLATFORM_FUCHSIA
#    include <zircon/process.h>
#    include <zircon/syscalls.h>
#else
#    include <sys/resource.h>
#endif

namespace angle
{

namespace
{
std::string GetModulePath(void *moduleOrSymbol)
{
    Dl_info dlInfo;
    if (dladdr(moduleOrSymbol, &dlInfo) == 0)
    {
        return "";
    }

#ifdef ANGLE_PLATFORM_LINUX
    // Chrome changes process title on Linux that causes dladdr returns wrong module
    // file name for executable binary, so return GetExecutablePath() if dli_fname
    // doesn't exist.
    struct stat buf;
    if (stat(dlInfo.dli_fname, &buf) != 0)
    {
        return GetExecutablePath();
    }
#endif

    return dlInfo.dli_fname;
}

void *OpenPosixLibrary(const std::string &fullPath, int extraFlags, std::string *errorOut)
{
    void *module = dlopen(fullPath.c_str(), RTLD_NOW | extraFlags);
    if (module)
    {
        if (errorOut)
        {
            *errorOut = fullPath;
        }
    }
    else if (errorOut)
    {
        *errorOut = "dlopen(";
        *errorOut += fullPath;
        *errorOut += ") failed with error: ";
        *errorOut += dlerror();
        struct stat sfile;
        if (-1 == stat(fullPath.c_str(), &sfile))
        {
            *errorOut += ", stat() call failed.";
        }
        else
        {
            *errorOut += ", stat() info: ";
            struct passwd *pwuser = getpwuid(sfile.st_uid);
            if (pwuser)
            {
                *errorOut += "owner: ";
                *errorOut += pwuser->pw_name;
                *errorOut += ", ";
            }
            struct group *grpnam = getgrgid(sfile.st_gid);
            if (grpnam)
            {
                *errorOut += "group: ";
                *errorOut += grpnam->gr_name;
                *errorOut += ", ";
            }
            *errorOut += "perms: ";
            *errorOut += std::to_string(sfile.st_mode);
            *errorOut += ", links: ";
            *errorOut += std::to_string(sfile.st_nlink);
            *errorOut += ", size: ";
            *errorOut += std::to_string(sfile.st_size);
        }
    }
    return module;
}
}  // namespace

Optional<std::string> GetCWD()
{
    std::array<char, 4096> pathBuf;
    char *result = getcwd(pathBuf.data(), pathBuf.size());
    if (result == nullptr)
    {
        return Optional<std::string>::Invalid();
    }
    return std::string(pathBuf.data());
}

bool SetCWD(const char *dirName)
{
    return (chdir(dirName) == 0);
}

bool UnsetEnvironmentVar(const char *variableName)
{
    return (unsetenv(variableName) == 0);
}

bool SetEnvironmentVar(const char *variableName, const char *value)
{
    return (setenv(variableName, value, 1) == 0);
}

std::string GetEnvironmentVar(const char *variableName)
{
    const char *value = getenv(variableName);
    return (value == nullptr ? std::string() : std::string(value));
}

const char *GetPathSeparatorForEnvironmentVar()
{
    return ":";
}

std::string GetModuleDirectoryAndGetError(std::string *errorOut)
{
    std::string directory;
    static int placeholderSymbol = 0;
    std::string moduleName       = GetModulePath(&placeholderSymbol);
    if (!moduleName.empty())
    {
        directory = moduleName.substr(0, moduleName.find_last_of('/') + 1);
    }

    // Ensure we return the full path to the module, not the relative path
    if (!IsFullPath(directory))
    {
        if (errorOut)
        {
            *errorOut += "Directory: '";
            *errorOut += directory;
            *errorOut += "' is not full path";
        }
        Optional<std::string> cwd = GetCWD();
        if (cwd.valid())
        {
            directory = ConcatenatePath(cwd.value(), directory);
            if (errorOut)
            {
                *errorOut += ", so it has been modified to: '";
                *errorOut += directory;
                *errorOut += "'. ";
            }
        }
        else if (errorOut)
        {
            *errorOut += " and getcwd was invalid. ";
        }
    }
    return directory;
}

std::string GetModuleDirectory()
{
    return GetModuleDirectoryAndGetError(nullptr);
}

void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName,
                                                SearchType searchType,
                                                std::string *errorOut)
{
    std::string directory;
    if (searchType == SearchType::ModuleDir)
    {
#if ANGLE_PLATFORM_IOS_FAMILY
        // On iOS, shared libraries must be loaded from within the app bundle.
        directory = GetExecutableDirectory() + "/Frameworks/";
#elif ANGLE_PLATFORM_FUCHSIA
        // On Fuchsia the dynamic loader always looks up libraries in /pkg/lib
        // and disallows loading of libraries via absolute paths.
        directory = "";
#else
        directory = GetModuleDirectoryAndGetError(errorOut);
#endif
    }

    int extraFlags = 0;
    if (searchType == SearchType::AlreadyLoaded)
    {
        extraFlags = RTLD_NOLOAD;
    }

    std::string fullPath = directory + libraryName;
    return OpenPosixLibrary(fullPath, extraFlags, errorOut);
}

void *GetLibrarySymbol(void *libraryHandle, const char *symbolName)
{
    if (!libraryHandle)
    {
        return nullptr;
    }

    return dlsym(libraryHandle, symbolName);
}

std::string GetLibraryPath(void *libraryHandle)
{
    if (!libraryHandle)
    {
        return "";
    }

    return GetModulePath(libraryHandle);
}

void CloseSystemLibrary(void *libraryHandle)
{
    if (libraryHandle)
    {
        dlclose(libraryHandle);
    }
}

bool IsDirectory(const char *filename)
{
    struct stat st;
    int result = stat(filename, &st);
    return result == 0 && ((st.st_mode & S_IFDIR) == S_IFDIR);
}

bool IsDebuggerAttached()
{
    // This could have a fuller implementation.
    // See https://cs.chromium.org/chromium/src/base/debug/debugger_posix.cc
    return false;
}

bool IsSameFileDescriptor(int fd1, int fd2)
{
    struct stat stat1, stat2;
    if (fstat(fd1, &stat1) < 0)
    {
        return false;
    }
    if (fstat(fd2, &stat2) < 0)
    {
        return false;
    }
    // Comparing st_ino (the unique identifier within a filesystem) and
    // st_dev (the identifier of the filesystem) uniquely identifies a
    // file within a POSIX-conforming system
    return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
}

void BreakDebugger()
{
    // This could have a fuller implementation.
    // See https://cs.chromium.org/chromium/src/base/debug/debugger_posix.cc
    abort();
}

const char *GetExecutableExtension()
{
    return "";
}

char GetPathSeparator()
{
    return '/';
}

std::string GetRootDirectory()
{
    return "/";
}

bool CreateDirectories(const std::string &path)
{
    // First sanitize path so we can use "/" as universal path separator
    std::string sanitizedPath(path);
    MakeForwardSlashThePathSeparator(sanitizedPath);

    size_t pos = 0;
    do
    {
        pos = sanitizedPath.find("/", pos);
        std::string checkPath(sanitizedPath.substr(0, pos));
        if (!checkPath.empty() && !IsDirectory(checkPath.c_str()))
        {
            if (mkdir(checkPath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == -1)
            {
                return false;
            }
        }
        if (pos == std::string::npos)
        {
            break;
        }
        ++pos;
    } while (true);
    return true;
}

void MakeForwardSlashThePathSeparator(std::string &path)
{
    // Nothing to do here for *nix side
    return;
}

Optional<std::string> GetTempDirectory()
{
    const char *tmp = getenv("TMPDIR");
    if (tmp != nullptr)
    {
        return std::string(tmp);
    }

#if defined(ANGLE_PLATFORM_ANDROID)
    // Not used right now in the ANGLE test runner.
    // return PathService::Get(DIR_CACHE, path);
    return Optional<std::string>::Invalid();
#else
    return std::string("/tmp");
#endif
}

Optional<std::string> CreateTemporaryFileInDirectory(const std::string &directory)
{
    return CreateTemporaryFileInDirectoryWithExtension(directory, std::string());
}

Optional<std::string> CreateTemporaryFileInDirectoryWithExtension(const std::string &directory,
                                                                  const std::string &extension)
{
    std::string tempFileTemplate = directory + "/.angle.XXXXXX" + extension;

    int fd = mkstemps(&tempFileTemplate[0], static_cast<int>(extension.size()));
    close(fd);

    if (fd != -1)
    {
        return tempFileTemplate;
    }

    return Optional<std::string>::Invalid();
}

double GetCurrentProcessCpuTime()
{
#ifdef ANGLE_PLATFORM_FUCHSIA
    static zx_handle_t me = zx_process_self();
    zx_info_task_runtime_t task_runtime;
    zx_object_get_info(me, ZX_INFO_TASK_RUNTIME, &task_runtime, sizeof(task_runtime), nullptr,
                       nullptr);
    return static_cast<double>(task_runtime.cpu_time) * 1e-9;
#else
    // We could also have used /proc/stat, but that requires us to read the
    // filesystem and convert from jiffies. /proc/stat also relies on jiffies
    // (lower resolution) while getrusage can potentially use a sched_clock()
    // underneath that has higher resolution.
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    double userTime   = usage.ru_utime.tv_sec + usage.ru_utime.tv_usec * 1e-6;
    double systemTime = usage.ru_stime.tv_sec + usage.ru_stime.tv_usec * 1e-6;
    return userTime + systemTime;
#endif
}

namespace
{
bool SetMemoryProtection(uintptr_t start, size_t size, int protections)
{
    int ret = mprotect(reinterpret_cast<void *>(start), size, protections);
    if (ret < 0)
    {
        perror("mprotect failed");
    }
    return ret == 0;
}

class PosixPageFaultHandler : public PageFaultHandler
{
  public:
    PosixPageFaultHandler(PageFaultCallback callback) : PageFaultHandler(callback) {}
    ~PosixPageFaultHandler() override {}

    bool enable() override;
    bool disable() override;
    void handle(int sig, siginfo_t *info, void *unused);

  private:
    struct sigaction mDefaultBusAction  = {};
    struct sigaction mDefaultSegvAction = {};
};

PosixPageFaultHandler *gPosixPageFaultHandler = nullptr;
void SegfaultHandlerFunction(int sig, siginfo_t *info, void *unused)
{
    gPosixPageFaultHandler->handle(sig, info, unused);
}

void PosixPageFaultHandler::handle(int sig, siginfo_t *info, void *unused)
{
    bool found = false;
    if ((sig == SIGSEGV || sig == SIGBUS) &&
        (info->si_code == SEGV_ACCERR || info->si_code == SEGV_MAPERR))
    {
        found = mCallback(reinterpret_cast<uintptr_t>(info->si_addr)) ==
                PageFaultHandlerRangeType::InRange;
    }

    // Fall back to default signal handler
    if (!found)
    {
        if (sig == SIGSEGV)
        {
            mDefaultSegvAction.sa_sigaction(sig, info, unused);
        }
        else if (sig == SIGBUS)
        {
            mDefaultBusAction.sa_sigaction(sig, info, unused);
        }
        else
        {
            UNREACHABLE();
        }
    }
}

bool PosixPageFaultHandler::disable()
{
    return sigaction(SIGSEGV, &mDefaultSegvAction, nullptr) == 0 &&
           sigaction(SIGBUS, &mDefaultBusAction, nullptr) == 0;
}

bool PosixPageFaultHandler::enable()
{
    struct sigaction sigAction = {};
    sigAction.sa_flags         = SA_SIGINFO;
    sigAction.sa_sigaction     = &SegfaultHandlerFunction;
    sigemptyset(&sigAction.sa_mask);

    // Some POSIX implementations use SIGBUS for mprotect faults
    return sigaction(SIGSEGV, &sigAction, &mDefaultSegvAction) == 0 &&
           sigaction(SIGBUS, &sigAction, &mDefaultBusAction) == 0;
}
}  // namespace

// Set write protection
bool ProtectMemory(uintptr_t start, size_t size)
{
    return SetMemoryProtection(start, size, PROT_READ);
}

// Allow reading and writing
bool UnprotectMemory(uintptr_t start, size_t size)
{
    return SetMemoryProtection(start, size, PROT_READ | PROT_WRITE);
}

size_t GetPageSize()
{
    long pageSize = sysconf(_SC_PAGE_SIZE);
    if (pageSize < 0)
    {
        perror("Could not get sysconf page size");
        return 0;
    }
    return static_cast<size_t>(pageSize);
}

PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback)
{
    gPosixPageFaultHandler = new PosixPageFaultHandler(callback);
    return gPosixPageFaultHandler;
}

uint64_t GetProcessMemoryUsageKB()
{
    FILE *file = fopen("/proc/self/status", "r");

    if (!file)
    {
        return 0;
    }

    const char *kSearchString           = "VmRSS:";
    constexpr size_t kMaxLineSize       = 100;
    std::array<char, kMaxLineSize> line = {};

    uint64_t kb = 0;

    while (fgets(line.data(), line.size(), file) != nullptr)
    {
        if (strncmp(line.data(), kSearchString, strlen(kSearchString)) == 0)
        {
            std::vector<std::string> strings;
            SplitStringAlongWhitespace(line.data(), &strings);

            sscanf(strings[1].c_str(), "%" SCNu64, &kb);
            break;
        }
    }
    fclose(file);

    return kb;
}
}  // namespace angle
