// 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() {
    // UNIMPLEMENTED
    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;
}
