/* Main program when embedded in a UWP application on Windows */

#include "Python.h"
#include <string.h>

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <shellapi.h>
#include <shlobj.h>

#include <string>

#if defined(__clang__)
#define _SILENCE_CLANG_COROUTINE_MESSAGE
#endif
#define _SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS

#include <appmodel.h>
#include <winrt\Windows.ApplicationModel.h>
#include <winrt\Windows.Storage.h>

#ifdef PYTHONW
#ifdef Py_DEBUG
const wchar_t *PROGNAME = L"pythonw_d.exe";
#else
const wchar_t *PROGNAME = L"pythonw.exe";
#endif
#else
#ifdef Py_DEBUG
const wchar_t *PROGNAME = L"python_d.exe";
#else
const wchar_t *PROGNAME = L"python.exe";
#endif
#endif

static std::wstring
get_package_family()
{
    try {
        UINT32 nameLength = MAX_PATH;
        std::wstring name;
        name.resize(nameLength);
        DWORD rc = GetCurrentPackageFamilyName(&nameLength, name.data());
        if (rc == ERROR_SUCCESS) {
            name.resize(nameLength - 1);
            return name;
        }
        else if (rc != ERROR_INSUFFICIENT_BUFFER) {
            throw rc;
        }
        name.resize(nameLength);
        rc = GetCurrentPackageFamilyName(&nameLength, name.data());
        if (rc != ERROR_SUCCESS) {
            throw rc;
        }
        name.resize(nameLength - 1);
        return name;
    }
    catch (...) {
    }

    return std::wstring();
}

static std::wstring
get_user_base()
{
    try {
        const auto appData = winrt::Windows::Storage::ApplicationData::Current();
        if (appData) {
            const auto localCache = appData.LocalCacheFolder();
            if (localCache) {
                std::wstring path { localCache.Path().c_str() };
                if (!path.empty()) {
                    return path + L"\\local-packages";
                }
            }
        }
    } catch (...) {
    }

    return std::wstring();
}

static std::wstring
get_package_home()
{
    try {
        UINT32 pathLength = MAX_PATH;
        std::wstring path;
        path.resize(pathLength);
        DWORD rc = GetCurrentPackagePath(&pathLength, path.data());
        if (rc == ERROR_SUCCESS) {
            path.resize(pathLength - 1);
            return path;
        }
        else if (rc != ERROR_INSUFFICIENT_BUFFER) {
            throw rc;
        }
        path.resize(pathLength);
        rc = GetCurrentPackagePath(&pathLength, path.data());
        if (rc != ERROR_SUCCESS) {
            throw rc;
        }
        path.resize(pathLength - 1);
        return path;
    }
    catch (...) {
    }

    return std::wstring();
}

static PyStatus
set_process_name(PyConfig *config)
{
    PyStatus status = PyStatus_Ok();
    std::wstring executable;

    const auto home = get_package_home();
    const auto family = get_package_family();

    if (!family.empty()) {
        PWSTR localAppData;
        if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0,
                                           NULL, &localAppData))) {
            executable = std::wstring(localAppData)
                         + L"\\Microsoft\\WindowsApps\\"
                         + family
                         + L"\\"
                         + PROGNAME;

            CoTaskMemFree(localAppData);
        }
    }

    /* Only use module filename if we don't have a home */
    if (home.empty() && executable.empty()) {
        executable.resize(MAX_PATH);
        while (true) {
            DWORD len = GetModuleFileNameW(
                NULL, executable.data(), (DWORD)executable.size());
            if (len == 0) {
                executable.clear();
                break;
            } else if (len == executable.size() &&
                       GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                executable.resize(len * 2);
            } else {
                executable.resize(len);
                break;
            }
        }
        size_t i = executable.find_last_of(L"/\\");
        if (i == std::wstring::npos) {
            executable = PROGNAME;
        } else {
            executable.replace(i + 1, std::wstring::npos, PROGNAME);
        }
    }

    if (!home.empty()) {
        status = PyConfig_SetString(config, &config->home, home.c_str());
        if (PyStatus_Exception(status)) {
            return status;
        }
    }

    const wchar_t *launcherPath = _wgetenv(L"__PYVENV_LAUNCHER__");
    if (launcherPath) {
        if (!executable.empty()) {
            status = PyConfig_SetString(config, &config->base_executable,
                                        executable.c_str());
            if (PyStatus_Exception(status)) {
                return status;
            }
        }

        status = PyConfig_SetString(
            config, &config->executable, launcherPath);

        /* bpo-35873: Clear the environment variable to avoid it being
        * inherited by child processes. */
        _wputenv_s(L"__PYVENV_LAUNCHER__", L"");
    } else if (!executable.empty()) {
        status = PyConfig_SetString(
            config, &config->executable, executable.c_str());
    }

    return status;
}

int
wmain(int argc, wchar_t **argv)
{
    PyStatus status;
    PyPreConfig preconfig;
    PyConfig config;

    const wchar_t *moduleName = NULL;
    const wchar_t *p = wcsrchr(argv[0], L'\\');
    if (!p) {
        p = argv[0];
    }
    if (p) {
        if (*p == L'\\') {
            p++;
        }

        if (wcsnicmp(p, L"pip", 3) == 0) {
            moduleName = L"pip";
        } else if (wcsnicmp(p, L"idle", 4) == 0) {
            moduleName = L"idlelib";
        }
    }

    PyPreConfig_InitPythonConfig(&preconfig);
    if (!moduleName) {
        status = Py_PreInitializeFromArgs(&preconfig, argc, argv);
        if (PyStatus_Exception(status)) {
            goto fail_without_config;
        }
    }

    PyConfig_InitPythonConfig(&config);

    status = PyConfig_SetArgv(&config, argc, argv);
    if (PyStatus_Exception(status)) {
        goto fail;
    }
    if (moduleName) {
        config.parse_argv = 0;
    }

    status = set_process_name(&config);
    if (PyStatus_Exception(status)) {
        goto fail;
    }

    p = _wgetenv(L"PYTHONUSERBASE");
    if (!p || !*p) {
        _wputenv_s(L"PYTHONUSERBASE", get_user_base().c_str());
    }

    if (moduleName) {
        status = PyConfig_SetString(&config, &config.run_module, moduleName);
        if (PyStatus_Exception(status)) {
            goto fail;
        }
        status = PyConfig_SetString(&config, &config.run_filename, NULL);
        if (PyStatus_Exception(status)) {
            goto fail;
        }
        status = PyConfig_SetString(&config, &config.run_command, NULL);
        if (PyStatus_Exception(status)) {
            goto fail;
        }
    }

    status = Py_InitializeFromConfig(&config);
    if (PyStatus_Exception(status)) {
        goto fail;
    }
    PyConfig_Clear(&config);

    return Py_RunMain();

fail:
    PyConfig_Clear(&config);
fail_without_config:
    if (PyStatus_IsExit(status)) {
        return status.exitcode;
    }
    assert(PyStatus_Exception(status));
    Py_ExitStatusException(status);
    /* Unreachable code */
    return 0;
}

#ifdef PYTHONW

int WINAPI wWinMain(
    HINSTANCE hInstance,      /* handle to current instance */
    HINSTANCE hPrevInstance,  /* handle to previous instance */
    LPWSTR lpCmdLine,         /* pointer to command line */
    int nCmdShow              /* show state of window */
)
{
    return wmain(__argc, __wargv);
}

#endif
