/*
* Copyright (C) 2014 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.
*/

#include "stdafx.h"
#include "utils.h"

// Set to true to get some extra debug information
bool gIsDebug = false;
// Set to true to output errors to stderr (for a Console app)
// or to false to output using msg box (for a Windows UI app)
bool gIsConsole = false;

// Application name used in error dialog. Defined using initUtils()
static CString gAppName("Find Java 2");

// Called by the application to initialize the app name used in error dialog boxes.
void initUtils(const TCHAR *appName) {
    if (appName != NULL) {
        gAppName = CString(appName);
        return;
    }

    // Try to get the VERSIONINFO.FileDescription and use as app name
    // Errors are ignored, in which case the default app name is used.

    // First get the module (aka app instance) filename.
    TCHAR moduleName[MAX_PATH + 1];
    DWORD sz = ::GetModuleFileName(NULL /*AfxGetInstanceHandle()*/, moduleName, MAX_PATH);
    if (sz == 0) {
        // GetModuleFileName failed. Do nothing.
        return;
    }
    moduleName[sz] = '\0';  // make sure string is properly terminated.

    // Get the size of the FileVersionInfo buffer
    DWORD obsoleteHandle; // see http://blogs.msdn.com/b/oldnewthing/archive/2007/07/31/4138786.aspx
    DWORD fviSize = ::GetFileVersionInfoSize(moduleName, &obsoleteHandle);
    if (fviSize == 0) {
        return; // do nothing on error
    }

    char *fviBuffer = new char[fviSize];
    if (::GetFileVersionInfo(moduleName, 0, fviSize, fviBuffer) != 0) {
        VOID *vBuffer;
        UINT vLen;

        struct LANGUAGE_CODEPAGE {
            WORD mLanguage;
            WORD mCodePage;
        } *lgcpBuffer;

        UINT lgcpSize;

        // Read the list of languages and code pages (c.f. MSDN for VerQueryValue)
        if (::VerQueryValue(fviBuffer, _T("\\VarFileInfo\\Translation"), (LPVOID*)&lgcpBuffer, &lgcpSize) != 0 &&
                lgcpSize >= sizeof(LANGUAGE_CODEPAGE)) {
            // Use the first available language and code page
            CString subBlock;
            subBlock.Format(_T("\\StringFileInfo\\%04x%04x\\FileDescription"),
                            lgcpBuffer[0].mLanguage,
                            lgcpBuffer[0].mCodePage);
            if (::VerQueryValue(fviBuffer, subBlock, &vBuffer, &vLen) != 0) {
                gAppName.SetString((LPCTSTR)vBuffer, vLen);
            }
        }
    }
    delete[] fviBuffer;
}

CString getAppName() {
    return gAppName;
}


// Displays a message in an ok+info dialog box.
void msgBox(const TCHAR* text, ...) {
    CString formatted;
    va_list ap;
    va_start(ap, text);
    formatted.FormatV(text, ap);
    va_end(ap);

    // TODO global CString to get app name
    MessageBox(NULL, formatted, gAppName, MB_OK | MB_ICONINFORMATION);
}

// Sets the string to the message matching Win32 GetLastError.
// If message is non-null, it is prepended to the last error string.
CString getLastWin32Error(const TCHAR* message) {
    DWORD err = GetLastError();
    CString result;
    LPTSTR errStr;
    if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */
                      FORMAT_MESSAGE_FROM_SYSTEM,
                      NULL,                             /* lpSource */
                      err,                              /* dwMessageId */
                      0,                                /* dwLanguageId */
                      (LPTSTR) &errStr,                 /* out lpBuffer */
                      0,                                /* nSize */
                      NULL) != 0) {                     /* va_list args */
        if (message == NULL) {
            result.Format(_T("[%d] %s"), err, errStr);
        } else {
            result.Format(_T("%s[%d] %s"), message, err, errStr);
        }
        LocalFree(errStr);
    }
    return result;
}

// Displays GetLastError prefixed with a description in an error dialog box
void displayLastError(const TCHAR *description, ...) {
    CString formatted;
    va_list ap;
    va_start(ap, description);
    formatted.FormatV(description, ap);
    va_end(ap);

    CString error = getLastWin32Error(NULL);
    formatted.Append(_T("\r\n"));
    formatted.Append(error);

    if (gIsConsole) {
        _ftprintf(stderr, _T("%s\n"), (LPCTSTR) formatted);
    } else {
        CString name(gAppName);
        name.Append(_T(" - Error"));
        MessageBox(NULL, formatted, name, MB_OK | MB_ICONERROR);
    }
}

// Executes the command line. Does not wait for the program to finish.
// The return code is from CreateProcess (0 means failure), not the running app.
int execNoWait(const TCHAR *app, const TCHAR *params, const TCHAR *workDir) {
    STARTUPINFO           startup;
    PROCESS_INFORMATION   pinfo;

    ZeroMemory(&pinfo, sizeof(pinfo));

    ZeroMemory(&startup, sizeof(startup));
    startup.cb = sizeof(startup);
    startup.dwFlags = STARTF_USESHOWWINDOW;
    startup.wShowWindow = SW_SHOWDEFAULT;

    int ret = CreateProcess(
        app,                                        /* program path */
        (TCHAR *)params,                            /* command-line */
        NULL,                  /* process handle is not inheritable */
        NULL,                   /* thread handle is not inheritable */
        TRUE,                          /* yes, inherit some handles */
        0,                                          /* create flags */
        NULL,                     /* use parent's environment block */
        workDir,                 /* use parent's starting directory */
        &startup,                 /* startup info, i.e. std handles */
        &pinfo);

    if (ret) {
        CloseHandle(pinfo.hProcess);
        CloseHandle(pinfo.hThread);
    }

    return ret;
}

// Executes command, waits for completion and returns exit code.
// As indicated in MSDN for CreateProcess, callers should double-quote the program name
// e.g. cmd="\"c:\program files\myapp.exe\" arg1 arg2";
int execWait(const TCHAR *cmd) {
    STARTUPINFO           startup;
    PROCESS_INFORMATION   pinfo;

    ZeroMemory(&pinfo, sizeof(pinfo));

    ZeroMemory(&startup, sizeof(startup));
    startup.cb = sizeof(startup);
    startup.dwFlags = STARTF_USESHOWWINDOW;
    startup.wShowWindow = SW_HIDE | SW_MINIMIZE;

    int ret = CreateProcess(
        NULL,                                       /* program path */
        (LPTSTR)cmd,                                /* command-line */
        NULL,                  /* process handle is not inheritable */
        NULL,                   /* thread handle is not inheritable */
        TRUE,                          /* yes, inherit some handles */
        CREATE_NO_WINDOW,                /* we don't want a console */
        NULL,                     /* use parent's environment block */
        NULL,                    /* use parent's starting directory */
        &startup,                 /* startup info, i.e. std handles */
        &pinfo);

    int result = -1;
    if (ret) {
        WaitForSingleObject(pinfo.hProcess, INFINITE);

        DWORD exitCode;
        if (GetExitCodeProcess(pinfo.hProcess, &exitCode)) {
            // this should not return STILL_ACTIVE (259)
            result = exitCode;
        }
        CloseHandle(pinfo.hProcess);
        CloseHandle(pinfo.hThread);
    }

    return result;
}

bool getModuleDir(CPath *outDir) {
    TCHAR programDir[MAX_PATH];
    int ret = GetModuleFileName(NULL, programDir, sizeof(programDir) / sizeof(programDir[0]));
    if (ret != 0) {
        CPath dir(programDir);
        dir.RemoveFileSpec();
        *outDir = dir;
        return true;
    }
    return false;
}

// Disables the FS redirection done by WOW64.
// Because this runs as a 32-bit app, Windows automagically remaps some
// folder under the hood (e.g. "Programs Files(x86)" is mapped as "Program Files").
// This prevents the app from correctly searching for java.exe in these folders.
// The registry is also remapped. This method disables this redirection.
// Caller should restore the redirection later by using revertWow64FsRedirection().
PVOID disableWow64FsRedirection() {

    // The call we want to make is the following:
    //    PVOID oldWow64Value;
    //    Wow64DisableWow64FsRedirection(&oldWow64Value);
    // However that method may not exist (e.g. on XP non-64 systems) so
    // we must not call it directly.

    PVOID oldWow64Value = 0;

    HMODULE hmod = LoadLibrary(_T("kernel32.dll"));
    if (hmod != NULL) {
        FARPROC proc = GetProcAddress(hmod, "Wow64DisableWow64FsRedirection");
        if (proc != NULL) {
            typedef BOOL(WINAPI *disableWow64FuncType)(PVOID *);
            disableWow64FuncType funcPtr = (disableWow64FuncType)proc;
            funcPtr(&oldWow64Value);
        }

        FreeLibrary(hmod);
    }

    return oldWow64Value;
}

// Reverts the redirection disabled in disableWow64FsRedirection.
void revertWow64FsRedirection(PVOID oldWow64Value) {

    // The call we want to make is the following:
    //    Wow64RevertWow64FsRedirection(oldWow64Value);
    // However that method may not exist (e.g. on XP non-64 systems) so
    // we must not call it directly.

    HMODULE hmod = LoadLibrary(_T("kernel32.dll"));
    if (hmod != NULL) {
        FARPROC proc = GetProcAddress(hmod, "Wow64RevertWow64FsRedirection");
        if (proc != NULL) {
            typedef BOOL(WINAPI *revertWow64FuncType)(PVOID);
            revertWow64FuncType funcPtr = (revertWow64FuncType)proc;
            funcPtr(oldWow64Value);
        }

        FreeLibrary(hmod);
    }
}
