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

#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
