// Copyright 2019 The Dawn Authors
//
// 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 "dawn/common/SystemUtils.h"

#include "dawn/common/Assert.h"
#include "dawn/common/Log.h"

#if defined(DAWN_PLATFORM_WINDOWS)
#    include <Windows.h>
#    include <vector>
#elif defined(DAWN_PLATFORM_LINUX)
#    include <dlfcn.h>
#    include <limits.h>
#    include <unistd.h>
#    include <cstdlib>
#elif defined(DAWN_PLATFORM_MACOS) || defined(DAWN_PLATFORM_IOS)
#    include <dlfcn.h>
#    include <mach-o/dyld.h>
#    include <vector>
#endif

#include <array>

#if defined(DAWN_PLATFORM_WINDOWS)
const char* GetPathSeparator() {
    return "\\";
}

std::pair<std::string, bool> GetEnvironmentVar(const char* variableName) {
    // First pass a size of 0 to get the size of variable value.
    DWORD sizeWithNullTerminator = GetEnvironmentVariableA(variableName, nullptr, 0);
    if (sizeWithNullTerminator == 0) {
        DWORD err = GetLastError();
        if (err != ERROR_ENVVAR_NOT_FOUND) {
            dawn::WarningLog() << "GetEnvironmentVariableA failed with code " << err;
        }
        return std::make_pair(std::string(), false);
    }

    // Then get variable value with its actual size.
    std::vector<char> buffer(sizeWithNullTerminator);
    DWORD sizeStored =
        GetEnvironmentVariableA(variableName, buffer.data(), static_cast<DWORD>(buffer.size()));
    if (sizeStored + 1 != sizeWithNullTerminator) {
        DWORD err = GetLastError();
        if (err) {
            dawn::WarningLog() << "GetEnvironmentVariableA failed with code " << err;
        }
        return std::make_pair(std::string(), false);
    }
    return std::make_pair(std::string(buffer.data(), sizeStored), true);
}

bool SetEnvironmentVar(const char* variableName, const char* value) {
    return SetEnvironmentVariableA(variableName, value) == TRUE;
}
#elif defined(DAWN_PLATFORM_POSIX)
const char* GetPathSeparator() {
    return "/";
}

std::pair<std::string, bool> GetEnvironmentVar(const char* variableName) {
    char* value = getenv(variableName);
    return value == nullptr ? std::make_pair(std::string(), false)
                            : std::make_pair(std::string(value), true);
}

bool SetEnvironmentVar(const char* variableName, const char* value) {
    if (value == nullptr) {
        return unsetenv(variableName) == 0;
    }
    return setenv(variableName, value, 1) == 0;
}
#else
#    error "Implement Get/SetEnvironmentVar for your platform."
#endif

#if defined(DAWN_PLATFORM_WINDOWS)
std::optional<std::string> GetHModulePath(HMODULE module) {
    std::array<char, MAX_PATH> executableFileBuf;
    DWORD executablePathLen = GetModuleFileNameA(nullptr, executableFileBuf.data(),
                                                 static_cast<DWORD>(executableFileBuf.size()));
    if (executablePathLen == 0) {
        return {};
    }
    return executableFileBuf.data();
}
std::optional<std::string> GetExecutablePath() {
    return GetHModulePath(nullptr);
}
#elif defined(DAWN_PLATFORM_LINUX)
std::optional<std::string> GetExecutablePath() {
    std::array<char, PATH_MAX> path;
    ssize_t result = readlink("/proc/self/exe", path.data(), PATH_MAX - 1);
    if (result < 0 || static_cast<size_t>(result) >= PATH_MAX - 1) {
        return {};
    }

    path[result] = '\0';
    return path.data();
}
#elif defined(DAWN_PLATFORM_MACOS) || defined(DAWN_PLATFORM_IOS)
std::optional<std::string> GetExecutablePath() {
    uint32_t size = 0;
    _NSGetExecutablePath(nullptr, &size);

    std::vector<char> buffer(size + 1);
    if (_NSGetExecutablePath(buffer.data(), &size) != 0) {
        return {};
    }

    buffer[size] = '\0';
    return buffer.data();
}
#elif defined(DAWN_PLATFORM_FUCHSIA)
std::optional<std::string> GetExecutablePath() {
    // TODO: Implement on Fuchsia
    return {};
}
#elif defined(DAWN_PLATFORM_EMSCRIPTEN)
std::optional<std::string> GetExecutablePath() {
    return {};
}
#else
#    error "Implement GetExecutablePath for your platform."
#endif

std::optional<std::string> GetExecutableDirectory() {
    std::optional<std::string> exePath = GetExecutablePath();
    if (!exePath) {
        return {};
    }
    size_t lastPathSepLoc = exePath->find_last_of(GetPathSeparator());
    if (lastPathSepLoc == std::string::npos) {
        return {};
    }
    return exePath->substr(0, lastPathSepLoc + 1);
}

#if defined(DAWN_PLATFORM_LINUX) || defined(DAWN_PLATFORM_MACOS) || defined(DAWN_PLATFORM_IOS)
std::optional<std::string> GetModulePath() {
    static int placeholderSymbol = 0;
    Dl_info dlInfo;
    if (dladdr(&placeholderSymbol, &dlInfo) == 0) {
        return {};
    }

    std::array<char, PATH_MAX> absolutePath;
    if (realpath(dlInfo.dli_fname, absolutePath.data()) == NULL) {
        return {};
    }
    return absolutePath.data();
}
#elif defined(DAWN_PLATFORM_WINDOWS)
std::optional<std::string> GetModulePath() {
    static int placeholderSymbol = 0;
    HMODULE module = nullptr;
// GetModuleHandleEx is unavailable on UWP
#    if defined(DAWN_IS_WINUWP)
    return {};
#    else
    if (!GetModuleHandleExA(
            GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
            reinterpret_cast<LPCSTR>(&placeholderSymbol), &module)) {
        return {};
    }
#    endif
    return GetHModulePath(module);
}
#elif defined(DAWN_PLATFORM_FUCHSIA)
std::optional<std::string> GetModulePath() {
    return {};
}
#elif defined(DAWN_PLATFORM_EMSCRIPTEN)
std::optional<std::string> GetModulePath() {
    return {};
}
#else
#    error "Implement GetModulePath for your platform."
#endif

std::optional<std::string> GetModuleDirectory() {
    std::optional<std::string> modPath = GetModulePath();
    if (!modPath) {
        return {};
    }
    size_t lastPathSepLoc = modPath->find_last_of(GetPathSeparator());
    if (lastPathSepLoc == std::string::npos) {
        return {};
    }
    return modPath->substr(0, lastPathSepLoc + 1);
}

// ScopedEnvironmentVar

ScopedEnvironmentVar::ScopedEnvironmentVar(const char* variableName, const char* value)
    : mName(variableName),
      mOriginalValue(GetEnvironmentVar(variableName)),
      mIsSet(SetEnvironmentVar(variableName, value)) {
}

ScopedEnvironmentVar::~ScopedEnvironmentVar() {
    if (mIsSet) {
        bool success = SetEnvironmentVar(
            mName.c_str(), mOriginalValue.second ? mOriginalValue.first.c_str() : nullptr);
        // If we set the environment variable in the constructor, we should never fail restoring it.
        ASSERT(success);
    }
}

bool ScopedEnvironmentVar::Set(const char* variableName, const char* value) {
    ASSERT(!mIsSet);
    mName = variableName;
    mOriginalValue = GetEnvironmentVar(variableName);
    mIsSet = SetEnvironmentVar(variableName, value);
    return mIsSet;
}
