/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
 /*
 * Author: Tomas Holy
 */

#ifndef _WIN32_WINNT        
#define _WIN32_WINNT 0x05010100
#endif

#include <shlobj.h>
#include "nblauncher.h"
#include "../bootstrap/utilsfuncs.h"
#include "../bootstrap/argnames.h"
#include "../bootstrap/nbexecloader.h"

using namespace std;

const char *NbLauncher::NBEXEC_FILE_PATH = NBEXEC_DLL;
const char *NbLauncher::OPT_NB_DEFAULT_USER_DIR = "netbeans_default_userdir=";
const char *NbLauncher::OPT_NB_DEFAULT_CACHE_DIR = "netbeans_default_cachedir=";
const char *NbLauncher::OPT_NB_DEFAULT_OPTIONS = "netbeans_default_options=";
const char *NbLauncher::OPT_NB_EXTRA_CLUSTERS = "netbeans_extraclusters=";
const char *NbLauncher::OPT_NB_JDK_HOME = "netbeans_jdkhome=";
const char *NbLauncher::ENV_USER_PROFILE = "USERPROFILE";
const char *NbLauncher::HOME_TOKEN = "${HOME}";
const char *NbLauncher::DEFAULT_USERDIR_ROOT_TOKEN = "${DEFAULT_USERDIR_ROOT}";
const char *NbLauncher::DEFAULT_CACHEDIR_ROOT_TOKEN = "${DEFAULT_CACHEDIR_ROOT}";
const char *NbLauncher::NETBEANS_DIRECTORY = "\\NetBeans\\";
const char *NbLauncher::NETBEANS_CACHES_DIRECTORY = "\\NetBeans\\Cache\\";

const char *NbLauncher::CON_ATTACH_MSG = 
"\n\nThe launcher has determined that the parent process has a console and will reuse it for its own console output.\n"
"Closing the console will result in termination of the running program.\n"
"Use '--console suppress' to suppress console output.\n"
"Use '--console new' to create a separate console window.\n";

const char *NbLauncher::staticOptions[] = {
    "-J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade",
    "--branding",
    "nb"
};

NbLauncher::NbLauncher() {
}

NbLauncher::NbLauncher(const NbLauncher& orig) {
}

NbLauncher::~NbLauncher() {
}

int NbLauncher::start(char *cmdLine) {
    CmdArgs args(50);
    args.addCmdLine(cmdLine);
    return start(args.getCount(), args.getArgs());
}

int NbLauncher::start(int argc, char *argv[]) {
    SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
    
    DWORD parentProcID = 0;
    if (!checkLoggingArg(argc, argv, true) || !setupProcess(argc, argv, parentProcID, CON_ATTACH_MSG) || !initBaseNames() || !readClusterFile()) {
        return -1;
    }

    parseConfigFile((baseDir + "\\etc\\" + getAppName() + ".conf").c_str());

    if (!parseArgs(argc, argv)) {
        return -1;
    }
    string oldUserDir = userDir;
    parseConfigFile((userDir + "\\etc\\" + getAppName() + ".conf").c_str());
    userDir = oldUserDir;

    addExtraClusters();
    string nbexecPath;
    SetDllDirectory(baseDir.c_str());
    if (dirExists(platformDir.c_str())) {
        nbexecPath = platformDir;
    } else {
        nbexecPath = baseDir + '\\' + platformDir;
    }
    if (!dirExists(nbexecPath.c_str())) {
        logErr(false, true, "Could not find platform cluster:\n%s", nbexecPath.c_str());
        return false;
    }

    CmdArgs newArgs(argc + 20);
    addSpecificOptions(newArgs);
    
    if (!clusters.empty()) {
        newArgs.add(ARG_NAME_CLUSTERS);
        newArgs.add(clusters.c_str());
    }
    if (!userDir.empty()) {
        newArgs.add(ARG_NAME_USER_DIR);
        newArgs.add(userDir.c_str());
    }
    if (!defUserDirRoot.empty()) {
        newArgs.add(ARG_DEFAULT_USER_DIR_ROOT);
        newArgs.add(defUserDirRoot.c_str());
    }
    if (!cacheDir.empty() && !customUserDirFound) {
        newArgs.add(ARG_NAME_CACHE_DIR);
        newArgs.add(cacheDir.c_str());
    }
    if (!nbOptions.empty()) {
        newArgs.addCmdLine(nbOptions.c_str());
    }
    for (int i = 0; i < argc; i++) {
        newArgs.add(argv[i]);
    }
    if (!jdkHome.empty()) {
        newArgs.add(ARG_NAME_JDKHOME);
        newArgs.add(jdkHome.c_str());
    }
    if (parentProcID) {
        newArgs.add(ARG_NAME_LA_PPID);
        char tmp[16] = "";
        newArgs.add(itoa(parentProcID, tmp, 10));
    }
    nbexecPath += NBEXEC_FILE_PATH;

    const char *curDir = getCurrentDir();
    if (curDir) {
        char olddir[MAX_PATH];
        DWORD rc = GetCurrentDirectory(MAX_PATH, olddir);
        if (rc == 0) {
            logErr(true, false, "Failed to get current directory");
        } else {
            string od = string(olddir);
            od.insert(0, "-J-Dnetbeans.user.dir=");
            newArgs.add(od.c_str());
        }
        logMsg("Changing current directory to: \"%s\"", curDir);
        SetCurrentDirectory(curDir);
    }

    NBExecLoader loader;
    return loader.start(nbexecPath.c_str(), newArgs.getCount(), newArgs.getArgs());
}

bool NbLauncher::initBaseNames() {
    char path[MAX_PATH] = "";
    getCurrentModulePath(path, MAX_PATH);
    logMsg("Executable: %s", path);
    char *bslash = strrchr(path, '\\');
    if (!bslash) {
        return false;
    }
    appName = bslash + 1;
    appName.erase(appName.rfind('.'));
    
    if (ARCHITECTURE == 64) {
        appName = appName.erase(appName.length() - 2);
    }
    
    logMsg("Application name: %s", appName.c_str());

    *bslash = '\0';
    bslash = strrchr(path, '\\');
    if (!bslash) {
        return false;
    }
    *bslash = '\0';        

    baseDir = path;
    
    /* The JavaVMOption.optionString interface forces us to stick to ANSI
    strings only, using whichever codepage is the default on the current Windows
    installation (e.g. windows-1252 for US Windows). For any Unicode characters
    that cannot be encoded using the current ANSI codepage, Win32 functions
    such as GetModuleFileName (used by getCurrentModulePath) and
    GetCurrentDirectory will substitute a question mark, which we detect here.
    Note that the ANSI codepage is a superset of ASCII; it can accomodate a
    limited selection of international characters that Microsoft once considered
    appropriate for the current Windows locale.

    It would be easy enough to switch the launcher process to UTF-8 everywhere;
    this can be configured from the manifest file
    (see https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page ).
    String types in these sources could remain as "char *" rather than
    wchar_t. The problem is that JNI will still seems to expect parameters to be
    passed using the default Windows codepage.

    I tried setting UTF8 in the manifests and using the --fork-java parameter
    to use the old CreateProcess launcher rather than JNI, but this still
    causes a "Could not find or load main class org.netbeans.Main" error. I
    also tried doing MultiByteToWideChar from UTF8 to wchar_t and calling
    CreateProcessW; it does not fix the problem even though changing the command
    line to prefix "cmd /c echo" causes my Cyrillic test character to show up
    correctly on the Windows command line.

    Other approaches which were attempted, but demeed too fragile:
    1) Set the current directory to baseDir and pass relative paths only.
       (Still led to ClassNotFoundException from ProxyClassLoader, which would
       have needed to be fixed. And doesn't work e.g. for the home directory,
       e.g. if the username itself has problematic characters in it.)
    2) Using the GetShortPathNameW function to get an equivalent
       Windows 95 style "8.3" compatibility path (e.g. "C:\Users\CHARTE~1").
       This worked, but is too likely to create problems down the line.
    */
    for (size_t i = 0; i < baseDir.size(); ++i) {
        if (baseDir[i] == '?') {
            logErr(false, true, "Cannot run in this folder; the path \"%s\" contains problematic characters.", path);
            return false;
        }
    }
    
    logMsg("Base dir: %s", baseDir.c_str());
    return true;
}

void NbLauncher::addCluster(const char *cluster) {

    class SetCurDir {
    public:
        SetCurDir(const char *dir) {
            oldCurDir[0] = '\0';
            DWORD rc = GetCurrentDirectory(MAX_PATH, oldCurDir);
            if (rc == 0) {
                logErr(true, false, "Failed to get current directory");
                return;
            }
            if (rc > MAX_PATH) {
                logMsg("Failed to get current directory, buffer is too small.");
                return;
            }
            if (!SetCurrentDirectory(dir)) {
                logErr(true, true, "Failed to set current directory to \"%s\"", dir);
                oldCurDir[0] = '\0';
            }
        }

        ~SetCurDir() {
            if (oldCurDir[0]) {
                if (!SetCurrentDirectory(oldCurDir)) {
                    logErr(true, true, "Failed to set current directory to \"%s\"", oldCurDir);
                }
            }
        }
    private:
        char oldCurDir[MAX_PATH];
    };

    logMsg("addCluster: %s", cluster);
    SetCurDir setCurDir(baseDir.c_str());
    char clusterPath[MAX_PATH + 1] = {0};
    strncpy(clusterPath, cluster, MAX_PATH);
    if (!normalizePath(clusterPath, MAX_PATH)) {
        logMsg("Invalid cluster path: %s", cluster);
        return;
    }
    if (!clusters.empty()) {
        clusters += ';';
    }
    logMsg("Adding cluster %s", clusterPath);
    clusters += clusterPath;
}

void NbLauncher::addExtraClusters() {
    logMsg("addExtraClusters()");
    const char delim = ';';
    string::size_type start = extraClusters.find_first_not_of(delim, 0);
    string::size_type end = extraClusters.find_first_of(delim, start);
    while (string::npos != end || string::npos != start) {
        string cluster = extraClusters.substr(start, end - start);
        addCluster(cluster.c_str());
        start = extraClusters.find_first_not_of(delim, end);
        end = extraClusters.find_first_of(delim, start);
    }
}

bool NbLauncher::readClusterFile() {
    clusters = "";
    string clusterFile = baseDir + "\\etc\\" + getAppName() + ".clusters";
    logMsg("readClusterFile() file: %s", clusterFile.c_str());

    FILE* file = fopen(clusterFile.c_str(), "r");
    if (!file) {
        logErr(true, true, "Cannot open file \"%s\" for reading.", clusterFile.c_str());
        return false;
    }

    char line[4096] = "";
    while (fgets(line, sizeof(line), file)) {
        char *str = skipWhitespaces(line);
        if (*str == '#' || *str == '\0') {
            continue;
        }
        char *pc = str;
        while (*pc != '\0' && *pc != '\t' && *pc != '\n' && *pc != '\r') {
            pc++;
        }
        *pc = '\0';

        if (platformDir.empty()) {
            char *slash = strrchr(str, '\\');
            if (!slash) {
                slash = strrchr(str, '/');
            }
            char *dir = slash ? slash + 1 : str;
            if (strncmp(dir, "platform", strlen("platform")) == 0) {
                platformDir = str;
            } else {
                addCluster(str);
            }
        } else {
            addCluster(str);
        }
    }
    bool ok = ferror(file) == 0;
    if (!ok) {
        logErr(true, true, "Error while reading file \"%s\".", clusterFile.c_str());
    }
    fclose(file);
    return ok;
}

bool NbLauncher::parseArgs(int argc, char *argv[]) {
#define CHECK_ARG \
    if (i+1 == argc) {\
        logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]);\
        return false;\
    }

    logMsg("parseArgs():");
    for (int i = 0; i < argc; i++) {
        logMsg("\t%s", argv[i]);
    }
    customUserDirFound = 0;
    for (int i = 0; i < argc; i++) {
        if (strcmp(ARG_NAME_USER_DIR, argv[i]) == 0) {
            CHECK_ARG;
            char tmp[MAX_PATH + 1] = {0};
            strncpy(tmp, argv[++i], MAX_PATH);
            if (!normalizePath(tmp, MAX_PATH)) {
                logErr(false, true, "User directory path \"%s\" is not valid.", argv[i]);
                return false;
            }
            customUserDirFound = 1;
            userDir = tmp;
            logMsg("User dir: %s", userDir.c_str());
        }
        if (strcmp(ARG_NAME_CACHE_DIR, argv[i]) == 0) {
            CHECK_ARG;
            char tmp[MAX_PATH + 1] = {0};
            strncpy(tmp, argv[++i], MAX_PATH);
            if (!normalizePath(tmp, MAX_PATH)) {
                logErr(false, true, "Cache directory path \"%s\" is not valid.", argv[i]);
                return false;
            }
            cacheDir = tmp;
            logMsg("Cache dir: %s", cacheDir.c_str());
        }
    }
    logMsg("parseArgs() finished");
    return true;
}

bool NbLauncher::findUserDir(const char *str) {
    logMsg("NbLauncher::findUserDir()");    
    if (strncmp(str, HOME_TOKEN, strlen(HOME_TOKEN)) == 0) {
        if (userHome.empty()) {
            char *userProfile = getenv(ENV_USER_PROFILE);
            if (userProfile) {
                userHome = userProfile;
            } else {
                TCHAR userHomeChar[MAX_PATH]; 
                if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, userHomeChar))) {    
                    return false;
                }
                userHome = userHomeChar;
                userHome.erase(userHome.rfind('\\'));
            }
            logMsg("User home: %s", userHome.c_str());
        }
        userDir = userHome + (str + strlen(HOME_TOKEN));
    } else if (strncmp(str, DEFAULT_USERDIR_ROOT_TOKEN, strlen(DEFAULT_USERDIR_ROOT_TOKEN)) == 0) {       
        std::string s = std::string("Replacing ") + DEFAULT_USERDIR_ROOT_TOKEN;
        logMsg(s.c_str());
        userDir = getDefaultUserDirRoot() + (str + strlen(DEFAULT_USERDIR_ROOT_TOKEN));
    } else {
        getDefaultUserDirRoot();
        userDir = str;
    }
    return true;
}

bool NbLauncher::findCacheDir(const char *str) {
    logMsg("NbLauncher::findCacheDir()");
    if (strncmp(str, HOME_TOKEN, strlen(HOME_TOKEN)) == 0) {
        if (userHome.empty()) {
            char *userProfile = getenv(ENV_USER_PROFILE);
            if (userProfile) {
                userHome = userProfile;
            } else {
                TCHAR userHomeChar[MAX_PATH]; 
                if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, userHomeChar))) {    
                    return false;
                }
                userHome = userHomeChar;
                userHome.erase(userHome.rfind('\\'));
            }
            logMsg("User home: %s", userHome.c_str());
        }
        cacheDir = userHome + (str + strlen(HOME_TOKEN));
    } else if (strncmp(str, DEFAULT_CACHEDIR_ROOT_TOKEN, strlen(DEFAULT_CACHEDIR_ROOT_TOKEN)) == 0) {   
        std::string s = std::string("Replacing ") + DEFAULT_CACHEDIR_ROOT_TOKEN;
        logMsg(s.c_str());
        cacheDir = getDefaultCacheDirRoot() + (str + strlen(DEFAULT_CACHEDIR_ROOT_TOKEN));
    } else {
        getDefaultCacheDirRoot();
        cacheDir = str;
    }
    return true;
}

string NbLauncher::getDefaultUserDirRoot() {
    TCHAR defUserDirRootChar[MAX_PATH];
    if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, defUserDirRootChar))) {
        return std::string();
    }
    defUserDirRoot = constructApplicationDir((string) defUserDirRootChar, false);
    defUserDirRoot.erase(defUserDirRoot.rfind('\\'));
    logMsg("Default Userdir Root: %s", defUserDirRoot.c_str());
    return defUserDirRoot;
}

string NbLauncher::getDefaultCacheDirRoot() {
    TCHAR defCacheDirRootChar[MAX_PATH];
    if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, defCacheDirRootChar))) {
        return std::string();
    }
    defCacheDirRoot = constructApplicationDir((string) defCacheDirRootChar, true);
    defCacheDirRoot.erase(defCacheDirRoot.rfind('\\'));
    logMsg("Default Cachedir Root: %s", defCacheDirRoot.c_str());
    return defCacheDirRoot;
}

bool NbLauncher::getOption(char *&str, const char *opt) {
    if (strncmp(str, opt, strlen(opt)) == 0) {
        str += strlen(opt);
        char *end = trimWhitespaces(str);
        if (*str == '"') {
            str++;
        }
        if (end >= str && *end == '"') {
            *end = '\0';
        }
        logMsg("Option found: %s%s", opt, str);
        return true;
    }
    return false;
}

bool NbLauncher::parseConfigFile(const char* path) {
    logMsg("parseConfigFile(%s)", path);
    FILE *file = fopen(path, "r");
    if (!file) {
        logErr(true, false, "Cannot open file \"%s\" for reading.", path);
        return false;
    }
    
    char line[4096] = "";
    while (fgets(line, sizeof(line), file)) {
        char *str = skipWhitespaces(line);
        if (*str == '#') {
            continue;
        }
        if (getOption(str, getDefUserDirOptName())) {
             findUserDir(str);
             logMsg("User dir: %s", userDir.c_str());
        } else if (getOption(str, getDefCacheDirOptName())) {
             findCacheDir(str);
             logMsg("Cache dir: %s", cacheDir.c_str());
        } else if (getOption(str, getDefOptionsOptName())) {
            // replace \" by "
            int len = strlen(str);
            int k = 0;
            for (int i = 0; i < len; i++) {
                if (str[i] == '\\' && str[i+1] == '\"') {
                    continue;
                }
                str[k++] = str[i];
            }
            str[k] = '\0';
            nbOptions = str;
            logMsg("After replacement: %s", nbOptions.c_str());

        } else if (getOption(str, getExtraClustersOptName())) {
            extraClusters = str;
        } else if (getOption(str, getJdkHomeOptName())) {
            jdkHome = str;
        }
    }
    bool ok = ferror(file) == 0;
    if (!ok) {
        logErr(true, false, "Error while reading file \"%s\".", path);
    }
    fclose(file);
    return true;
}

typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);

const char * NbLauncher::getAppName() {
    return "netbeans";
}

void NbLauncher::addSpecificOptions(CmdArgs &args) {
    for (unsigned i = 0; i < sizeof (staticOptions) / sizeof (char*); i++) {
        args.add(staticOptions[i]);
    }
}

const char * NbLauncher::getDefUserDirOptName() {
    return OPT_NB_DEFAULT_USER_DIR;
}

const char * NbLauncher::getDefCacheDirOptName() {
    return OPT_NB_DEFAULT_CACHE_DIR;
}


const char * NbLauncher::getDefOptionsOptName() {
    return OPT_NB_DEFAULT_OPTIONS;
}

const char * NbLauncher::getExtraClustersOptName() {
    return OPT_NB_EXTRA_CLUSTERS;
}

const char * NbLauncher::getJdkHomeOptName() {
    return OPT_NB_JDK_HOME;
}

const char * NbLauncher::getCurrentDir() {
    return 0;
}

std::string NbLauncher::constructApplicationDir(const std::string& dir, bool cache) {
   if (cache) {
       return dir + NETBEANS_CACHES_DIRECTORY;
   } else {
       return dir + NETBEANS_DIRECTORY;
   }
}
