//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "os_helpers.h"
#include "errorHelpers.h"

// =================================================================================================
// C++ interface.
// =================================================================================================

#include <cerrno> // errno, error constants
#include <climits> // PATH_MAX
#include <cstdlib> // abort, _splitpath, _makepath
#include <cstring> // strdup, strerror_r
#include <sstream>

#include <vector>

#if defined(__ANDROID__)
#include <android/api-level.h>
#endif

#define CHECK_PTR(ptr)                                                         \
    if ((ptr) == NULL)                                                         \
    {                                                                          \
        abort();                                                               \
    }

typedef std::vector<char> buffer_t;

#if !defined(PATH_MAX)
#define PATH_MAX 1000
#endif

int const _size = PATH_MAX + 1; // Initial buffer size for path.
int const _count = 8; // How many times we will try to double buffer size.

// -------------------------------------------------------------------------------------------------
// MacOS X
// -------------------------------------------------------------------------------------------------

#if defined(__APPLE__)


#include <mach-o/dyld.h> // _NSGetExecutablePath
#include <libgen.h> // dirname


static std::string
_err_msg(int err, // Error number (e. g. errno).
         int level // Nesting level, for avoiding infinite recursion.
)
{

    /*
        There are 3 incompatible versions of strerror_r:

            char * strerror_r( int, char *, size_t );  // GNU version
            int    strerror_r( int, char *, size_t );  // BSD version
            int    strerror_r( int, char *, size_t );  // XSI version

        BSD version returns error code, while XSI version returns 0 or -1 and
       sets errno.

    */

    // BSD version of strerror_r.
    buffer_t buffer(100);
    int count = _count;
    for (;;)
    {
        int rc = strerror_r(err, &buffer.front(), buffer.size());
        if (rc == EINVAL)
        {
            // Error code is not recognized, but anyway we got the message.
            return &buffer.front();
        }
        else if (rc == ERANGE)
        {
            // Buffer is not enough.
            if (count > 0)
            {
                // Enlarge the buffer.
                --count;
                buffer.resize(buffer.size() * 2);
            }
            else
            {
                std::stringstream ostr;
                ostr << "Error " << err << " "
                     << "(Getting error message failed: "
                     << "Buffer of " << buffer.size()
                     << " bytes is still too small"
                     << ")";
                return ostr.str();
            }; // if
        }
        else if (rc == 0)
        {
            // We got the message.
            return &buffer.front();
        }
        else
        {
            std::stringstream ostr;
            ostr << "Error " << err << " "
                 << "(Getting error message failed: "
                 << (level < 2 ? _err_msg(rc, level + 1) : "Oops") << ")";
            return ostr.str();
        }; // if
    }; // forever

} // _err_msg


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


std::string exe_path()
{
    buffer_t path(_size);
    int count = _count;
    for (;;)
    {
        uint32_t size = path.size();
        int rc = _NSGetExecutablePath(&path.front(), &size);
        if (rc == 0)
        {
            break;
        }; // if
        if (count > 0)
        {
            --count;
            path.resize(size);
        }
        else
        {
            log_error("ERROR: Getting executable path failed: "
                      "_NSGetExecutablePath failed: Buffer of %lu bytes is "
                      "still too small\n",
                      (unsigned long)path.size());
            exit(2);
        }; // if
    }; // forever
    return &path.front();
} // exe_path


std::string exe_dir()
{
    std::string path = exe_path();
    // We cannot pass path.c_str() to `dirname' bacause `dirname' modifies its
    // argument.
    buffer_t buffer(path.c_str(),
                    path.c_str() + path.size() + 1); // Copy with trailing zero.
    return dirname(&buffer.front());
} // exe_dir


#endif // __APPLE__

// -------------------------------------------------------------------------------------------------
// Linux
// -------------------------------------------------------------------------------------------------

#if defined(__linux__)


#include <cerrno> // errno
#include <libgen.h> // dirname
#include <unistd.h> // readlink


static std::string _err_msg(int err, int level)
{

    /*
        There are 3 incompatible versions of strerror_r:

            char * strerror_r( int, char *, size_t );  // GNU version
            int    strerror_r( int, char *, size_t );  // BSD version
            int    strerror_r( int, char *, size_t );  // XSI version

        BSD version returns error code, while XSI version returns 0 or -1 and
       sets errno.

    */

#if (defined(__ANDROID__) && __ANDROID_API__ < 23)                             \
    || ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE)

// XSI version of strerror_r.
#warning Not tested!
    buffer_t buffer(200);
    int count = _count;
    for (;;)
    {
        int rc = strerror_r(err, &buffer.front(), buffer.size());
        if (rc == -1)
        {
            int _err = errno;
            if (_err == ERANGE)
            {
                if (count > 0)
                {
                    // Enlarge the buffer.
                    --count;
                    buffer.resize(buffer.size() * 2);
                }
                else
                {
                    std::stringstream ostr;
                    ostr << "Error " << err << " "
                         << "(Getting error message failed: "
                         << "Buffer of " << buffer.size()
                         << " bytes is still too small"
                         << ")";
                    return ostr.str();
                }; // if
            }
            else
            {
                std::stringstream ostr;
                ostr << "Error " << err << " "
                     << "(Getting error message failed: "
                     << (level < 2 ? _err_msg(_err, level + 1) : "Oops") << ")";
                return ostr.str();
            }; // if
        }
        else
        {
            // We got the message.
            return &buffer.front();
        }; // if
    }; // forever

#else

    // GNU version of strerror_r.
    char buffer[2000];
    return strerror_r(err, buffer, sizeof(buffer));

#endif

} // _err_msg


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


std::string exe_path()
{

    static std::string const exe = "/proc/self/exe";

    buffer_t path(_size);
    int count = _count; // Max number of iterations.

    for (;;)
    {

        ssize_t len = readlink(exe.c_str(), &path.front(), path.size());

        if (len < 0)
        {
            // Oops.
            int err = errno;
            log_error("ERROR: Getting executable path failed: "
                      "Reading symlink `%s' failed: %s\n",
                      exe.c_str(), err_msg(err).c_str());
            exit(2);
        }; // if

        if (len < path.size())
        {
            // We got the path.
            path.resize(len);
            break;
        }; // if

        // Oops, buffer is too small.
        if (count > 0)
        {
            --count;
            // Enlarge the buffer.
            path.resize(path.size() * 2);
        }
        else
        {
            log_error("ERROR: Getting executable path failed: "
                      "Reading symlink `%s' failed: Buffer of %lu bytes is "
                      "still too small\n",
                      exe.c_str(), (unsigned long)path.size());
            exit(2);
        }; // if

    }; // forever

    return std::string(&path.front(), path.size());

} // exe_path


std::string exe_dir()
{
    std::string path = exe_path();
    // We cannot pass path.c_str() to `dirname' bacause `dirname' modifies its
    // argument.
    buffer_t buffer(path.c_str(),
                    path.c_str() + path.size() + 1); // Copy with trailing zero.
    return dirname(&buffer.front());
} // exe_dir

#endif // __linux__

// -------------------------------------------------------------------------------------------------
// MS Windows
// -------------------------------------------------------------------------------------------------

#if defined(_WIN32)


#include <windows.h>
#if defined(max)
#undef max
#endif

#include <cctype>
#include <algorithm>


static std::string _err_msg(int err, int level)
{

    std::string msg;

    LPSTR buffer = NULL;
    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
        | FORMAT_MESSAGE_IGNORE_INSERTS;

    DWORD len = FormatMessageA(flags, NULL, err, LANG_USER_DEFAULT,
                               reinterpret_cast<LPSTR>(&buffer), 0, NULL);

    if (buffer == NULL || len == 0)
    {

        int _err = GetLastError();
        char str[1024] = { 0 };
        snprintf(str, sizeof(str),
                 "Error 0x%08x (Getting error message failed: %s )", err,
                 (level < 2 ? _err_msg(_err, level + 1).c_str() : "Oops"));
        msg = std::string(str);
    }
    else
    {

        // Trim trailing whitespace (including `\r' and `\n').
        while (len > 0 && isspace(buffer[len - 1]))
        {
            --len;
        }; // while

        // Drop trailing full stop.
        if (len > 0 && buffer[len - 1] == '.')
        {
            --len;
        }; // if

        msg.assign(buffer, len);

    }; // if

    if (buffer != NULL)
    {
        LocalFree(buffer);
    }; // if

    return msg;

} // _get_err_msg


std::string dir_sep() { return "\\"; } // dir_sep


std::string exe_path()
{

    buffer_t path(_size);
    int count = _count;

    for (;;)
    {

        DWORD len = GetModuleFileNameA(NULL, &path.front(), path.size());

        if (len == 0)
        {
            int err = GetLastError();
            log_error("ERROR: Getting executable path failed: %s\n",
                      err_msg(err).c_str());
            exit(2);
        }; // if

        if (len < path.size())
        {
            path.resize(len);
            break;
        }; // if

        // Buffer too small.
        if (count > 0)
        {
            --count;
            path.resize(path.size() * 2);
        }
        else
        {
            log_error("ERROR: Getting executable path failed: "
                      "Buffer of %lu bytes is still too small\n",
                      (unsigned long)path.size());
            exit(2);
        }; // if

    }; // forever

    return std::string(&path.front(), path.size());

} // exe_path


std::string exe_dir()
{

    std::string exe = exe_path();
    int count = 0;

    // Splitting path into components.
    buffer_t drv(_MAX_DRIVE);
    buffer_t dir(_MAX_DIR);
    count = _count;
#if defined(_MSC_VER)
    for (;;)
    {
        int rc =
            _splitpath_s(exe.c_str(), &drv.front(), drv.size(), &dir.front(),
                         dir.size(), NULL, 0, // We need neither name
                         NULL, 0 // nor extension
            );
        if (rc == 0)
        {
            break;
        }
        else if (rc == ERANGE)
        {
            if (count > 0)
            {
                --count;
                // Buffer is too small, but it is not clear which one.
                // So we have to enlarge all.
                drv.resize(drv.size() * 2);
                dir.resize(dir.size() * 2);
            }
            else
            {
                log_error("ERROR: Getting executable path failed: "
                          "Splitting path `%s' to components failed: "
                          "Buffers of %lu and %lu bytes are still too small\n",
                          exe.c_str(), (unsigned long)drv.size(),
                          (unsigned long)dir.size());
                exit(2);
            }; // if
        }
        else
        {
            log_error("ERROR: Getting executable path failed: "
                      "Splitting path `%s' to components failed: %s\n",
                      exe.c_str(), err_msg(rc).c_str());
            exit(2);
        }; // if
    }; // forever

#else // __MINGW32__

    // MinGW does not have the "secure" _splitpath_s, use the insecure version
    // instead.
    _splitpath(exe.c_str(), &drv.front(), &dir.front(),
               NULL, // We need neither name
               NULL // nor extension
    );
#endif // __MINGW32__

    // Combining components back to path.
    // I failed with "secure" `_makepath_s'. If buffer is too small, instead of
    // returning ERANGE, `_makepath_s' pops up dialog box and offers to debug
    // the program. D'oh! So let us try to guess the size of result and go with
    // insecure `_makepath'.
    buffer_t path(std::max(drv.size() + dir.size(), size_t(_MAX_PATH)) + 10);
    _makepath(&path.front(), &drv.front(), &dir.front(), NULL, NULL);

    return &path.front();

} // exe_dir


#endif // _WIN32


std::string err_msg(int err) { return _err_msg(err, 0); } // err_msg


// =================================================================================================
// C interface.
// =================================================================================================


char* get_err_msg(int err)
{
    char* msg = strdup(err_msg(err).c_str());
    CHECK_PTR(msg);
    return msg;
} // get_err_msg


char* get_dir_sep()
{
    char* sep = strdup(dir_sep().c_str());
    CHECK_PTR(sep);
    return sep;
} // get_dir_sep


char* get_exe_path()
{
    char* path = strdup(exe_path().c_str());
    CHECK_PTR(path);
    return path;
} // get_exe_path


char* get_exe_dir()
{
    char* dir = strdup(exe_dir().c_str());
    CHECK_PTR(dir);
    return dir;
} // get_exe_dir


// end of file //
