/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.
 */

#ifdef _WIN32

// Indicate we want at least all Windows Server 2003 (5.2) APIs.
// Note: default is set by system/core/include/arch/windows/AndroidConfig.h to 0x0500
// which is Win2K. However our minimum SDK tools requirement is Win XP (0x0501).
// However we do need 0x0502 to get access to the WOW-64-32 constants for the
// registry, except we'll need to be careful since they are not available on XP.
#undef  _WIN32_WINNT
#define _WIN32_WINNT 0x0502
// Indicate we want at least all IE 5 shell APIs
#define _WIN32_IE    0x0500

#include "find_java.h"
#include <shlobj.h>
#include <ctype.h>

// Define some types missing in MingW
#ifndef LSTATUS
typedef LONG LSTATUS;
#endif


// Extract the first thing that looks like (digit.digit+).
// Note: this will break when java reports a version with major > 9.
// However it will reasonably cope with "1.10", if that ever happens.
static bool extractJavaVersion(const char *start,
                               int length,
                               CString *outVersionStr,
                               int *outVersionInt) {
    const char *end = start + length;
    for (const char *c = start; c < end - 2; c++) {
        if (isdigit(c[0]) &&
                c[1] == '.' &&
                isdigit(c[2])) {
            const char *e = c+2;
            while (isdigit(e[1])) {
                e++;
            }
            if (outVersionStr != NULL) {
                outVersionStr->set(c, e - c + 1);
            }
            if (outVersionInt != NULL) {
                // add major * 1000, currently only 1 digit
                int value = (*c - '0') * 1000;
                // add minor
                for (int m = 1; *e != '.'; e--, m *= 10) {
                    value += (*e - '0') * m;
                }
                *outVersionInt = value;
            }
            return true;
        }
    }
    return false;
}

// Check whether we can find $PATH/java.exe.
// inOutPath should be the directory where we're looking at.
// In output, it will be the java path we tested.
// Returns the java version integer found (e.g. 1006 for 1.6).
// Return 0 in case of error.
static int checkPath(CPath *inOutPath) {
    inOutPath->addPath("java.exe");

    int result = 0;
    PVOID oldWow64Value = disableWow64FsRedirection();
    if (inOutPath->fileExists()) {
        // Run java -version
        // Reject the version if it's not at least our current minimum.
        if (!getJavaVersion(*inOutPath, NULL /*versionStr*/, &result)) {
            result = 0;
        }
    }

    revertWow64FsRedirection(oldWow64Value);
    return result;
}

// Check whether we can find $PATH/bin/java.exe
// Returns the Java version found (e.g. 1006 for 1.6) or 0 in case of error.
static int checkBinPath(CPath *inOutPath) {
    inOutPath->addPath("bin");
    return checkPath(inOutPath);
}

// Search java.exe in the environment
int findJavaInEnvPath(CPath *outJavaPath) {
    SetLastError(0);

    int currVersion = 0;

    const char* envPath = getenv("JAVA_HOME");
    if (envPath != NULL) {
        CPath p(envPath);
        currVersion = checkBinPath(&p);
        if (currVersion > 0) {
            if (gIsDebug) {
                fprintf(stderr, "Java %d found via JAVA_HOME: %s\n", currVersion, p.cstr());
            }
            *outJavaPath = p;
        }
        if (currVersion >= MIN_JAVA_VERSION) {
            // As an optimization for runtime, if we find a suitable java
            // version in JAVA_HOME we won't waste time looking at the PATH.
            return currVersion;
        }
    }

    envPath = getenv("PATH");
    if (!envPath) return currVersion;

    // Otherwise look at the entries in the current path.
    // If we find more than one, keep the one with the highest version.

    CArray<CString> *paths = CString(envPath).split(';');
    for(int i = 0; i < paths->size(); i++) {
        CPath p((*paths)[i].cstr());
        int v = checkPath(&p);
        if (v > currVersion) {
            if (gIsDebug) {
                fprintf(stderr, "Java %d found via env PATH: %s\n", v, p.cstr());
            }
            currVersion = v;
            *outJavaPath = p;
        }
    }

    delete paths;
    return currVersion;
}

// --------------

static bool getRegValue(const char *keyPath,
                        const char *keyName,
                        REGSAM access,
                        CString *outValue) {
    HKEY key;
    LSTATUS status = RegOpenKeyExA(
        HKEY_LOCAL_MACHINE,         // hKey
        keyPath,                    // lpSubKey
        0,                          // ulOptions
        KEY_READ | access,          // samDesired,
        &key);                      // phkResult
    if (status == ERROR_SUCCESS) {

        LSTATUS ret = ERROR_MORE_DATA;
        DWORD size = 4096; // MAX_PATH is 260, so 4 KB should be good enough
        char* buffer = (char*) malloc(size);

        while (ret == ERROR_MORE_DATA && size < (1<<16) /*64 KB*/) {
            ret = RegQueryValueExA(
                key,                // hKey
                keyName,            // lpValueName
                NULL,               // lpReserved
                NULL,               // lpType
                (LPBYTE) buffer,    // lpData
                &size);             // lpcbData

            if (ret == ERROR_MORE_DATA) {
                size *= 2;
                buffer = (char*) realloc(buffer, size);
            } else {
                buffer[size] = 0;
            }
        }

        if (ret != ERROR_MORE_DATA) outValue->set(buffer);

        free(buffer);
        RegCloseKey(key);

        return (ret != ERROR_MORE_DATA);
    }

    return false;
}

// Explore the registry to find a suitable version of Java.
// Returns an int which is the version of Java found (e.g. 1006 for 1.6) and the
// matching path in outJavaPath.
// Returns 0 if nothing suitable was found.
static int exploreJavaRegistry(const char *entry, REGSAM access, CPath *outJavaPath) {

    // Let's visit HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment [CurrentVersion]
    CPath rootKey("SOFTWARE\\JavaSoft\\");
    rootKey.addPath(entry);

    int versionInt = 0;
    CString currentVersion;
    CPath subKey(rootKey);
    if (getRegValue(subKey.cstr(), "CurrentVersion", access, &currentVersion)) {
        // CurrentVersion should be something like "1.7".
        // We want to read HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.7 [JavaHome]
        subKey.addPath(currentVersion);
        CPath javaHome;
        if (getRegValue(subKey.cstr(), "JavaHome", access, &javaHome)) {
            versionInt = checkBinPath(&javaHome);
            if (versionInt >= 0) {
                if (gIsDebug) {
                    fprintf(stderr,
                            "Java %d found via registry: %s\n",
                            versionInt, javaHome.cstr());
                }
                *outJavaPath = javaHome;
            }
            if (versionInt >= MIN_JAVA_VERSION) {
                // Heuristic: if the current version is good enough, stop here
                return versionInt;
            }
        }
    }

    // Try again, but this time look at all the versions available
    HKEY javaHomeKey;
    LSTATUS status = RegOpenKeyExA(
        HKEY_LOCAL_MACHINE,         // hKey
        "SOFTWARE\\JavaSoft",       // lpSubKey
        0,                          // ulOptions
        KEY_READ | access,          // samDesired
        &javaHomeKey);              // phkResult
    if (status == ERROR_SUCCESS) {
        char name[256];
        DWORD index = 0;
        CPath javaHome;
        for (LONG result = ERROR_SUCCESS; result == ERROR_SUCCESS; index++) {
            DWORD nameLen = 255;
            name[nameLen] = 0;
            result = RegEnumKeyExA(
                            javaHomeKey,  // hKey
                            index,        // dwIndex
                            name,         // lpName
                            &nameLen,     // lpcName
                            NULL,         // lpReserved
                            NULL,         // lpClass
                            NULL,         // lpcClass,
                            NULL);        // lpftLastWriteTime
            if (result == ERROR_SUCCESS && nameLen < 256) {
                name[nameLen] = 0;
                CPath subKey(rootKey);
                subKey.addPath(name);

                if (getRegValue(subKey.cstr(), "JavaHome", access, &javaHome)) {
                    int v = checkBinPath(&javaHome);
                    if (v > versionInt) {
                        if (gIsDebug) {
                            fprintf(stderr,
                                    "Java %d found via registry: %s\n",
                                    versionInt, javaHome.cstr());
                        }
                        *outJavaPath = javaHome;
                        versionInt = v;
                    }
                }
            }
        }

        RegCloseKey(javaHomeKey);
    }

    return 0;
}

static bool getMaxJavaInRegistry(const char *entry, REGSAM access, CPath *outJavaPath, int *inOutVersion) {
    CPath path;
    int version = exploreJavaRegistry(entry, access, &path);
    if (version > *inOutVersion) {
        *outJavaPath  = path;
        *inOutVersion = version;
        return true;
    }
    return false;
}

int findJavaInRegistry(CPath *outJavaPath) {
    // We'll do the registry test 3 times: first using the default mode,
    // then forcing the use of the 32-bit registry then forcing the use of
    // 64-bit registry. On Windows 2k, the 2 latter will fail since the
    // flags are not supported. On a 32-bit OS the 64-bit is obviously
    // useless and the 2 first tests should be equivalent so we just
    // need the first case.

    // Check the JRE first, then the JDK.
    int version = MIN_JAVA_VERSION - 1;
    bool result = false;
    result |= getMaxJavaInRegistry("Java Runtime Environment", 0, outJavaPath, &version);
    result |= getMaxJavaInRegistry("Java Development Kit",     0, outJavaPath, &version);

    // Get the app sysinfo state (the one hidden by WOW64)
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);
    WORD programArch = sysInfo.wProcessorArchitecture;
    // Check the real sysinfo state (not the one hidden by WOW64) for x86
    GetNativeSystemInfo(&sysInfo);
    WORD actualArch = sysInfo.wProcessorArchitecture;

    // Only try to access the WOW64-32 redirected keys on a 64-bit system.
    // There's no point in doing this on a 32-bit system.
    if (actualArch == PROCESSOR_ARCHITECTURE_AMD64) {
        if (programArch != PROCESSOR_ARCHITECTURE_INTEL) {
            // If we did the 32-bit case earlier, don't do it twice.
            result |= getMaxJavaInRegistry(
                "Java Runtime Environment", KEY_WOW64_32KEY, outJavaPath, &version);
            result |= getMaxJavaInRegistry(
                "Java Development Kit",     KEY_WOW64_32KEY, outJavaPath, &version);

        } else if (programArch != PROCESSOR_ARCHITECTURE_AMD64) {
            // If we did the 64-bit case earlier, don't do it twice.
            result |= getMaxJavaInRegistry(
                "Java Runtime Environment", KEY_WOW64_64KEY, outJavaPath, &version);
            result |= getMaxJavaInRegistry(
                "Java Development Kit",     KEY_WOW64_64KEY, outJavaPath, &version);
        }
    }

    return result ? version : 0;
}

// --------------

static bool checkProgramFiles(CPath *outJavaPath, int *inOutVersion) {

    char programFilesPath[MAX_PATH + 1];
    HRESULT result = SHGetFolderPathA(
        NULL,                       // hwndOwner
        CSIDL_PROGRAM_FILES,        // nFolder
        NULL,                       // hToken
        SHGFP_TYPE_CURRENT,         // dwFlags
        programFilesPath);          // pszPath
    if (FAILED(result)) return false;

    CPath path(programFilesPath);
    path.addPath("Java");

    // Do we have a C:\\Program Files\\Java directory?
    if (!path.dirExists()) return false;

    CPath glob(path);
    glob.addPath("j*");

    bool found = false;
    WIN32_FIND_DATAA findData;
    HANDLE findH = FindFirstFileA(glob.cstr(), &findData);
    if (findH == INVALID_HANDLE_VALUE) return false;
    do {
        if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
            CPath temp(path);
            temp.addPath(findData.cFileName);
            // Check C:\\Program Files[x86]\\Java\\j*\\bin\\java.exe
            int v = checkBinPath(&temp);
            if (v > *inOutVersion) {
                found = true;
                *inOutVersion = v;
                *outJavaPath = temp;
            }
        }
    } while (!found && FindNextFileA(findH, &findData) != 0);
    FindClose(findH);

    return found;
}

int findJavaInProgramFiles(CPath *outJavaPath) {

    // Check the C:\\Program Files (x86) directory
    // With WOW64 fs redirection in place by default, we should get the x86
    // version on a 64-bit OS since this app is a 32-bit itself.
    bool result = false;
    int version = MIN_JAVA_VERSION - 1;
    result |= checkProgramFiles(outJavaPath, &version);

    // Check the real sysinfo state (not the one hidden by WOW64) for x86
    SYSTEM_INFO sysInfo;
    GetNativeSystemInfo(&sysInfo);

    if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
        // On a 64-bit OS, try again by disabling the fs redirection so
        // that we can try the real C:\\Program Files directory.
        PVOID oldWow64Value = disableWow64FsRedirection();
        result |= checkProgramFiles(outJavaPath, &version);
        revertWow64FsRedirection(oldWow64Value);
    }

    return result ? version : 0;
}

// --------------


// Tries to invoke the java.exe at the given path and extract it's
// version number.
// - outVersionStr: if not null, will capture version as a string (e.g. "1.6")
// - outVersionInt: if not null, will capture version as an int (major * 1000 + minor, e.g. 1006).
bool getJavaVersion(CPath &javaPath, CString *outVersionStr, int *outVersionInt) {
    bool result = false;

    // Run "java -version", which outputs something like to *STDERR*:
    //
    // java version "1.6.0_29"
    // Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
    // Java HotSpot(TM) Client VM (build 20.4-b02, mixed mode, sharing)
    //
    // We want to capture the first line, and more exactly the "1.6" part.


    CString cmd;
    cmd.setf("\"%s\" -version", javaPath.cstr());

    SECURITY_ATTRIBUTES   saAttr;
    STARTUPINFO           startup;
    PROCESS_INFORMATION   pinfo;

    // Want to inherit pipe handle
    ZeroMemory(&saAttr, sizeof(saAttr));
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE; 
    saAttr.lpSecurityDescriptor = NULL; 

    // Create pipe for stdout
    HANDLE stdoutPipeRd, stdoutPipeWt;
    if (!CreatePipe(
            &stdoutPipeRd,      // hReadPipe,
            &stdoutPipeWt,      // hWritePipe,
            &saAttr,            // lpPipeAttributes,
            0)) {               // nSize (0=default buffer size)
        if (gIsConsole || gIsDebug) displayLastError("CreatePipe failed: ");
        return false;
    }
    if (!SetHandleInformation(stdoutPipeRd, HANDLE_FLAG_INHERIT, 0)) {
        if (gIsConsole || gIsDebug) displayLastError("SetHandleInformation failed: ");
        return false;
    }

    ZeroMemory(&pinfo, sizeof(pinfo));

    ZeroMemory(&startup, sizeof(startup));
    startup.cb          = sizeof(startup);
    startup.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    startup.wShowWindow = SW_HIDE|SW_MINIMIZE;
    // Capture both stderr and stdout
    startup.hStdError   = stdoutPipeWt;
    startup.hStdOutput  = stdoutPipeWt;
    startup.hStdInput   = GetStdHandle(STD_INPUT_HANDLE);

    BOOL ok = CreateProcessA(
            NULL,                   // program path
            (LPSTR) cmd.cstr(),     // command-line
            NULL,                   // process handle is not inheritable
            NULL,                   // thread handle is not inheritable
            TRUE,                   // yes, inherit some handles
            0,                      // process creation flags
            NULL,                   // use parent's environment block
            NULL,                   // use parent's starting directory
            &startup,               // startup info, i.e. std handles
            &pinfo);

    if ((gIsConsole || gIsDebug) && !ok) displayLastError("CreateProcess failed: ");

    // Close the write-end of the output pipe (we're only reading from it)
    CloseHandle(stdoutPipeWt);

    // Read from the output pipe. We don't need to read everything,
    // the first line should be 'Java version "1.2.3_45"\r\n'
    // so reading about 32 chars is all we need.
    char first32[32 + 1];
    int index = 0;
    first32[0] = 0;

    if (ok) {

        #define SIZE 1024
        char buffer[SIZE];
        DWORD sizeRead = 0;

        while (ok) {
            // Keep reading in the same buffer location
            ok = ReadFile(stdoutPipeRd,     // hFile
                          buffer,           // lpBuffer
                          SIZE,             // DWORD buffer size to read
                          &sizeRead,        // DWORD buffer size read
                          NULL);            // overlapped
            if (!ok || sizeRead == 0 || sizeRead > SIZE) break;

            // Copy up to the first 32 characters
            if (index < 32) {
                DWORD n = 32 - index;
                if (n > sizeRead) n = sizeRead;
                // copy as lowercase to simplify checks later
                for (char *b = buffer; n > 0; n--, b++, index++) {
                    char c = *b;
                    if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
                    first32[index] = c;
                }
                first32[index] = 0;
            }
        }

        WaitForSingleObject(pinfo.hProcess, INFINITE);

        DWORD exitCode;
        if (GetExitCodeProcess(pinfo.hProcess, &exitCode)) {
            // this should not return STILL_ACTIVE (259)
            result = exitCode == 0;
        }

        CloseHandle(pinfo.hProcess);
        CloseHandle(pinfo.hThread);
    }
    CloseHandle(stdoutPipeRd);

    if (result && index > 0) {
        // Look for a few keywords in the output however we don't
        // care about specific ordering or case-senstiviness.
        // We only captures roughtly the first line in lower case.
        char *j = strstr(first32, "java");
        char *v = strstr(first32, "version");
        if ((gIsConsole || gIsDebug) && (!j || !v)) {
            fprintf(stderr, "Error: keywords 'java version' not found in '%s'\n", first32);
        }
        if (j != NULL && v != NULL) {
            result = extractJavaVersion(first32, index, outVersionStr, outVersionInt);
        }
    }

    return result;
}


#endif /* _WIN32 */
