/*
 * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include <io.h>
#include <fcntl.h>
#include <stdlib.h>
#include <windows.h>

#include "CfgFile.h"
#include "AppLauncher.h"
#include "JvmLauncher.h"
#include "Log.h"
#include "Dll.h"
#include "WinApp.h"
#include "Toolbox.h"
#include "Executor.h"
#include "FileUtils.h"
#include "PackageFile.h"
#include "UniqueHandle.h"
#include "ErrorHandling.h"
#include "WinSysInfo.h"
#include "WinErrorHandling.h"


// AllowSetForegroundWindow - Requires linking with user32


namespace {

std::unique_ptr<Dll> loadDllWithAlteredPATH(const tstring& dllFullPath) {
    LOG_TRACE_FUNCTION();

    const tstring vanillaPathEnvVariable = SysInfo::getEnvVariable(_T("PATH"));

    tstring pathEnvVariable = vanillaPathEnvVariable
            + _T(";")
            + FileUtils::dirname(dllFullPath);

    SysInfo::setEnvVariable(_T("PATH"), pathEnvVariable);

    LOG_TRACE(tstrings::any() << "New value of PATH: " << pathEnvVariable);

    // Schedule restore of PATH after attempt to load the given dll
    const auto resetPATH = runAtEndOfScope([&vanillaPathEnvVariable]() -> void {
        SysInfo::setEnvVariable(_T("PATH"), vanillaPathEnvVariable);
    });

    return std::unique_ptr<Dll>(new Dll(dllFullPath));
}

std::unique_ptr<Dll> loadDllWithAddDllDirectory(const tstring& dllFullPath) {
    LOG_TRACE_FUNCTION();

    const tstring dirPath = FileUtils::dirname(dllFullPath);

    typedef DLL_DIRECTORY_COOKIE(WINAPI *AddDllDirectoryFunc)(PCWSTR);

    DllFunction<AddDllDirectoryFunc> _AddDllDirectory(
            Dll("kernel32.dll", Dll::System()), "AddDllDirectory");

    AddDllDirectoryFunc func = _AddDllDirectory;
    DLL_DIRECTORY_COOKIE res = func(dirPath.c_str());
    if (!res) {
        JP_THROW(SysError(tstrings::any()
                << "AddDllDirectory(" << dirPath << ") failed", func));
    }

    LOG_TRACE(tstrings::any() << "AddDllDirectory(" << dirPath << "): OK");

    // Important: use LOAD_LIBRARY_SEARCH_DEFAULT_DIRS flag,
    // but not LOAD_LIBRARY_SEARCH_USER_DIRS!
    HMODULE dllHandle = LoadLibraryEx(dllFullPath.c_str(), NULL,
            LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);

    LOG_TRACE(tstrings::any() << "LoadLibraryEx(" << dllFullPath
            << ", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS): " << dllHandle);

    const auto freeDll = runAtEndOfScope([&dllHandle]() -> void {
        Dll::freeLibrary(dllHandle);
    });

    return std::unique_ptr<Dll>(new Dll(dllFullPath));
}


class DllWrapper {
public:
    DllWrapper(const tstring& dllName) {
        try {
            // Adjust the DLL search paths with AddDllDirectory() WINAPI CALL
            dll = loadDllWithAddDllDirectory(dllName);
        } catch (const std::exception&) {
            // Alter PATH environment variable as the last resort.
            dll = loadDllWithAlteredPATH(dllName);
        }
    }

private:
    DllWrapper(const DllWrapper&);
    DllWrapper& operator=(const DllWrapper&);

private:
    std::unique_ptr<Dll> dll;
};


tstring getJvmLibPath(const Jvm& jvm) {
    FileUtils::mkpath path;

    path << FileUtils::dirname(jvm.getPath()) << _T("server") << _T("jvm.dll");

    return path;
}


void addCfgFileLookupDirForEnvVariable(
        const PackageFile& pkgFile, AppLauncher& appLauncher,
        const tstring& envVarName) {

    tstring path;
    JP_TRY;
    path = SysInfo::getEnvVariable(envVarName);
    JP_CATCH_ALL;

    if (!path.empty()) {
        appLauncher.addCfgFileLookupDir(FileUtils::mkpath() << path
                << pkgFile.getPackageName());
    }
}


class RunExecutorWithMsgLoop {
public:
    static DWORD apply(const Executor& exec) {
        RunExecutorWithMsgLoop instance(exec);

        UniqueHandle threadHandle = UniqueHandle(CreateThread(NULL, 0, worker,
                                    static_cast<LPVOID>(&instance), 0, NULL));
        if (threadHandle.get() == NULL) {
            JP_THROW(SysError("CreateThread() failed", CreateThread));
        }

        MSG msg;
        BOOL bRet;
        while((bRet = GetMessage(&msg, instance.hwnd, 0, 0 )) != 0) {
            if (bRet == -1) {
                JP_THROW(SysError("GetMessage() failed", GetMessage));
            } else {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }

        // Wait for worker thread to terminate to guarantee it will not linger
        // around after the thread running a message loop terminates.
        const DWORD res = ::WaitForSingleObject(threadHandle.get(), INFINITE);
        if (WAIT_FAILED ==  res) {
            JP_THROW(SysError("WaitForSingleObject() failed",
                                                        WaitForSingleObject));
        }

        LOG_TRACE(tstrings::any()
                            << "Executor worker thread terminated. Exit code="
                            << instance.exitCode);
        return instance.exitCode;
    }

private:
    RunExecutorWithMsgLoop(const Executor& v): exec(v) {
        exitCode = 1;

        // Message-only window.
        hwnd = CreateWindowEx(0, _T("STATIC"), _T(""), 0, 0, 0, 0, 0,
                              HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
        if (!hwnd) {
            JP_THROW(SysError("CreateWindowEx() failed", CreateWindowEx));
        }
    }

    static DWORD WINAPI worker(LPVOID param) {
        static_cast<RunExecutorWithMsgLoop*>(param)->run();
        return 0;
    }

    void run() {
        JP_TRY;
        exitCode = static_cast<DWORD>(exec.execAndWaitForExit());
        JP_CATCH_ALL;

        JP_TRY;
        if (!PostMessage(hwnd, WM_QUIT, 0, 0)) {
            JP_THROW(SysError("PostMessage(WM_QUIT) failed", PostMessage));
        }
        return;
        JP_CATCH_ALL;

        // All went wrong, PostMessage() failed. Just terminate with error code.
        exit(1);
    }

private:
    const Executor& exec;
    DWORD exitCode;
    HWND hwnd;
};


bool needRestartLauncher(AppLauncher& appLauncher, CfgFile& cfgFile) {
    if (appLauncher.libEnvVariableContainsAppDir()) {
        return false;
    }

    std::unique_ptr<CfgFile>(appLauncher.createCfgFile())->swap(cfgFile);

    const CfgFile::Properties& appOptions = cfgFile.getProperties(
            SectionName::Application);

    const CfgFile::Properties::const_iterator winNorestart = appOptions.find(
                PropertyName::winNorestart);

    bool result;
    if (winNorestart != appOptions.end()) {
        const bool norestart = CfgFile::asBoolean(*winNorestart);
        LOG_TRACE(tstrings::any() << PropertyName::winNorestart.name() << "="
                << (norestart ? "true" : "false") << " from config file");
        result = !norestart;
    } else {
        result = true;
    }

    appLauncher.setCfgFile(&cfgFile);

    return result;
}


void enableConsoleCtrlHandler(bool enable) {
    if (!SetConsoleCtrlHandler(NULL, enable ? FALSE : TRUE)) {
        JP_THROW(SysError(tstrings::any() << "SetConsoleCtrlHandler(NULL, "
                                            << (enable ? "FALSE" : "TRUE")
                                            << ") failed",
                                                    SetConsoleCtrlHandler));
    }
}


void launchApp() {
    // [RT-31061] otherwise UI can be left in back of other windows.
    ::AllowSetForegroundWindow(ASFW_ANY);

    const tstring launcherPath = SysInfo::getProcessModulePath();
    const tstring appImageRoot = FileUtils::dirname(launcherPath);
    const tstring appDirPath = FileUtils::mkpath() << appImageRoot << _T("app");

    const PackageFile pkgFile = PackageFile::loadFromAppDir(appDirPath);

    AppLauncher appLauncher = AppLauncher().setImageRoot(appImageRoot)
        .addJvmLibName(_T("bin\\jli.dll"))
        .setAppDir(appDirPath)
        .setLibEnvVariableName(_T("PATH"))
        .setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
            << _T("runtime"));

    if (!pkgFile.getPackageName().empty()) {
        addCfgFileLookupDirForEnvVariable(pkgFile, appLauncher, _T("LOCALAPPDATA"));
        addCfgFileLookupDirForEnvVariable(pkgFile, appLauncher, _T("APPDATA"));
    }

    CfgFile dummyCfgFile;
    const bool restart = needRestartLauncher(appLauncher, dummyCfgFile);

    std::unique_ptr<Jvm> jvm(appLauncher.createJvmLauncher());

    if (restart) {
        jvm->setEnvVariables();

        jvm = std::unique_ptr<Jvm>();

        UniqueHandle jobHandle(CreateJobObject(NULL, NULL));
        if (jobHandle.get() == NULL) {
            JP_THROW(SysError(tstrings::any() << "CreateJobObject() failed",
                                                            CreateJobObject));
        }
        JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = { };
        jobInfo.BasicLimitInformation.LimitFlags =
                JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
        if (!SetInformationJobObject(jobHandle.get(),
                JobObjectExtendedLimitInformation, &jobInfo, sizeof(jobInfo))) {
            JP_THROW(SysError(tstrings::any() <<
                                            "SetInformationJobObject() failed",
                                                    SetInformationJobObject));
        }

        Executor exec(launcherPath);
        exec.visible(true).withJobObject(jobHandle.get()).suspended(true).inherit(true);
        const auto args = SysInfo::getCommandArgs();
        std::for_each(args.begin(), args.end(), [&exec] (const tstring& arg) {
            exec.arg(arg);
        });

        exec.afterProcessCreated([&](HANDLE pid) {
            //
            // Ignore Ctrl+C in the current process.
            // This will prevent child process termination without allowing
            // it to handle Ctrl+C events.
            //
            // Disable the default Ctrl+C handler *after* the child process
            // has been created as it is inheritable and we want the child
            // process to have the default handler.
            //
            enableConsoleCtrlHandler(false);
        });

        DWORD exitCode = RunExecutorWithMsgLoop::apply(exec);

        exit(exitCode);
        return;
    }

    // zip.dll (and others) may be loaded by java without full path
    // make sure it will look in runtime/bin
    const tstring runtimeBinPath = FileUtils::dirname(jvm->getPath());
    SetDllDirectory(runtimeBinPath.c_str());
    LOG_TRACE(tstrings::any() << "SetDllDirectory to: " << runtimeBinPath);

    const DllWrapper jliDll(jvm->getPath());
    std::unique_ptr<DllWrapper> splashDll;
    if (jvm->isWithSplash()) {
        const DllWrapper jvmDll(getJvmLibPath(*jvm));
        splashDll = std::unique_ptr<DllWrapper>(new DllWrapper(
                FileUtils::mkpath()
                        << FileUtils::dirname(jvm->getPath())
                        << _T("splashscreen.dll")));
    }

    jvm->launch();
}

} // namespace

#ifndef JP_LAUNCHERW

int wmain() {
    return app::launch(std::nothrow, launchApp);
}

#else

int wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
    return app::wlaunch(std::nothrow, launchApp);
}

#endif
