//
// 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.
//

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

#include "system_utils.h"

#include <array>

#include <dlfcn.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

namespace angle
{

namespace
{
struct ScopedPipe
{
    ~ScopedPipe()
    {
        closeEndPoint(0);
        closeEndPoint(1);
    }
    void closeEndPoint(int index)
    {
        if (fds[index] >= 0)
        {
            close(fds[index]);
            fds[index] = -1;
        }
    }
    int fds[2] = {
        -1,
        -1,
    };
};

void ReadEntireFile(int fd, std::string *out)
{
    out->clear();

    while (true)
    {
        char buffer[256];
        ssize_t bytesRead = read(fd, buffer, sizeof(buffer));

        // If interrupted, retry.
        if (bytesRead < 0 && errno == EINTR)
        {
            continue;
        }

        // If failed, or nothing to read, we are done.
        if (bytesRead <= 0)
        {
            break;
        }

        out->append(buffer, bytesRead);
    }
}
}  // anonymous 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 *GetPathSeparator()
{
    return ":";
}

bool RunApp(const std::vector<const char *> &args,
            std::string *stdoutOut,
            std::string *stderrOut,
            int *exitCodeOut)
{
    if (args.size() == 0 || args.back() != nullptr)
    {
        return false;
    }

    ScopedPipe stdoutPipe;
    ScopedPipe stderrPipe;

    // Create pipes for stdout and stderr.
    if (stdoutOut && pipe(stdoutPipe.fds) != 0)
    {
        return false;
    }
    if (stderrOut && pipe(stderrPipe.fds) != 0)
    {
        return false;
    }

    pid_t pid = fork();
    if (pid < 0)
    {
        return false;
    }

    if (pid == 0)
    {
        // Child.  Execute the application.

        // Redirect stdout and stderr to the pipe fds.
        if (stdoutOut)
        {
            if (dup2(stdoutPipe.fds[1], STDOUT_FILENO) < 0)
            {
                _exit(errno);
            }
        }
        if (stderrOut)
        {
            if (dup2(stderrPipe.fds[1], STDERR_FILENO) < 0)
            {
                _exit(errno);
            }
        }

        // Execute the application, which doesn't return unless failed.  Note: execv takes argv as
        // `char * const *` for historical reasons.  It is safe to const_cast it:
        //
        // http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
        //
        // > The statement about argv[] and envp[] being constants is included to make explicit to
        // future writers of language bindings that these objects are completely constant. Due to a
        // limitation of the ISO C standard, it is not possible to state that idea in standard C.
        // Specifying two levels of const- qualification for the argv[] and envp[] parameters for
        // the exec functions may seem to be the natural choice, given that these functions do not
        // modify either the array of pointers or the characters to which the function points, but
        // this would disallow existing correct code. Instead, only the array of pointers is noted
        // as constant.
        execv(args[0], const_cast<char *const *>(args.data()));
        _exit(errno);
    }

    // Parent.  Read child output from the pipes and clean it up.

    // Close the write end of the pipes, so EOF can be generated when child exits.
    stdoutPipe.closeEndPoint(1);
    stderrPipe.closeEndPoint(1);

    // Read back the output of the child.
    if (stdoutOut)
    {
        ReadEntireFile(stdoutPipe.fds[0], stdoutOut);
    }
    if (stderrOut)
    {
        ReadEntireFile(stderrPipe.fds[0], stderrOut);
    }

    // Cleanup the child.
    int status = 0;
    do
    {
        pid_t changedPid = waitpid(pid, &status, 0);
        if (changedPid < 0 && errno == EINTR)
        {
            continue;
        }
        if (changedPid < 0)
        {
            return false;
        }
    } while (!WIFEXITED(status) && !WIFSIGNALED(status));

    // Retrieve the error code.
    if (exitCodeOut)
    {
        *exitCodeOut = WEXITSTATUS(status);
    }

    return true;
}

class PosixLibrary : public Library
{
  public:
    PosixLibrary(const char *libraryName, SearchType searchType)
    {
        std::string directory;
        if (searchType == SearchType::ApplicationDir)
        {
            static int dummySymbol = 0;
            Dl_info dlInfo;
            if (dladdr(&dummySymbol, &dlInfo) != 0)
            {
                std::string moduleName = dlInfo.dli_fname;
                directory              = moduleName.substr(0, moduleName.find_last_of('/') + 1);
            }
        }

        std::string fullPath = directory + libraryName + "." + GetSharedLibraryExtension();
        mModule              = dlopen(fullPath.c_str(), RTLD_NOW);
    }

    ~PosixLibrary() override
    {
        if (mModule)
        {
            dlclose(mModule);
        }
    }

    void *getSymbol(const char *symbolName) override
    {
        if (!mModule)
        {
            return nullptr;
        }

        return dlsym(mModule, symbolName);
    }

    void *getNative() const override { return mModule; }

  private:
    void *mModule = nullptr;
};

Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
{
    return new PosixLibrary(libraryName, searchType);
}

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;
}

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