/*
 * Copyright 2006-2007 Jacek Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "ole2.h"
#include "commctrl.h"
#include "advpub.h"
#include "wininet.h"
#include "shellapi.h"

#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/library.h"

#include "mshtml_private.h"
#include "resource.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

#ifdef __i386__
#define GECKO_ARCH "x86"
#else
#define GECKO_ARCH ""
#endif

#define GECKO_FILE_NAME "wine_gecko-" GECKO_VERSION "-" GECKO_ARCH ".cab"

static const WCHAR mshtml_keyW[] =
    {'S','o','f','t','w','a','r','e',
     '\\','W','i','n','e',
     '\\','M','S','H','T','M','L',0};

static HWND install_dialog = NULL;
static LPWSTR tmp_file_name = NULL;
static HANDLE tmp_file = INVALID_HANDLE_VALUE;
static LPWSTR url = NULL;

static void clean_up(void)
{
    if(tmp_file != INVALID_HANDLE_VALUE)
        CloseHandle(tmp_file);

    if(tmp_file_name) {
        DeleteFileW(tmp_file_name);
        heap_free(tmp_file_name);
        tmp_file_name = NULL;
    }

    if(tmp_file != INVALID_HANDLE_VALUE) {
        CloseHandle(tmp_file);
        tmp_file = INVALID_HANDLE_VALUE;
    }

    if(install_dialog)
        EndDialog(install_dialog, 0);
}

static void set_status(DWORD id)
{
    HWND status = GetDlgItem(install_dialog, ID_DWL_STATUS);
    WCHAR buf[64];

    LoadStringW(hInst, id, buf, sizeof(buf)/sizeof(WCHAR));
    SendMessageW(status, WM_SETTEXT, 0, (LPARAM)buf);
}

static void set_registry(LPCSTR install_dir)
{
    WCHAR mshtml_key[100];
    LPWSTR gecko_path;
    HKEY hkey;
    DWORD res, len;

    static const WCHAR wszGeckoPath[] = {'G','e','c','k','o','P','a','t','h',0};
    static const WCHAR wszWineGecko[] = {'w','i','n','e','_','g','e','c','k','o',0};

    memcpy(mshtml_key, mshtml_keyW, sizeof(mshtml_keyW));
    mshtml_key[sizeof(mshtml_keyW)/sizeof(WCHAR)-1] = '\\';
    MultiByteToWideChar(CP_ACP, 0, GECKO_VERSION, sizeof(GECKO_VERSION),
            mshtml_key+sizeof(mshtml_keyW)/sizeof(WCHAR),
            (sizeof(mshtml_key)-sizeof(mshtml_keyW))/sizeof(WCHAR));

    /* @@ Wine registry key: HKCU\Software\Wine\MSHTML\<version> */
    res = RegCreateKeyW(HKEY_CURRENT_USER, mshtml_key, &hkey);
    if(res != ERROR_SUCCESS) {
        ERR("Faild to create MSHTML key: %d\n", res);
        return;
    }

    len = MultiByteToWideChar(CP_ACP, 0, install_dir, -1, NULL, 0)-1;
    gecko_path = heap_alloc((len+1)*sizeof(WCHAR)+sizeof(wszWineGecko));
    MultiByteToWideChar(CP_ACP, 0, install_dir, -1, gecko_path, len+1);

    if (len && gecko_path[len-1] != '\\')
        gecko_path[len++] = '\\';

    memcpy(gecko_path+len, wszWineGecko, sizeof(wszWineGecko));

    res = RegSetValueExW(hkey, wszGeckoPath, 0, REG_SZ, (LPVOID)gecko_path,
                       len*sizeof(WCHAR)+sizeof(wszWineGecko));
    heap_free(gecko_path);
    RegCloseKey(hkey);
    if(res != ERROR_SUCCESS)
        ERR("Failed to set GeckoPath value: %08x\n", res);
}

static BOOL install_cab(LPCWSTR file_name)
{
    HMODULE advpack;
    char install_dir[MAX_PATH];
    HRESULT (WINAPI *pExtractFilesA)(LPCSTR,LPCSTR,DWORD,LPCSTR,LPVOID,DWORD);
    LPSTR file_name_a;
    DWORD res;
    HRESULT hres;

    static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};

    TRACE("(%s)\n", debugstr_w(file_name));

    GetSystemDirectoryA(install_dir, sizeof(install_dir));
    strcat(install_dir, "\\gecko\\");
    res = CreateDirectoryA(install_dir, NULL);
    if(!res && GetLastError() != ERROR_ALREADY_EXISTS) {
        ERR("Could not create directory: %08u\n", GetLastError());
        return FALSE;
    }

    strcat(install_dir, GECKO_VERSION);
    res = CreateDirectoryA(install_dir, NULL);
    if(!res && GetLastError() != ERROR_ALREADY_EXISTS) {
        ERR("Could not create directory: %08u\n", GetLastError());
        return FALSE;
    }

    advpack = LoadLibraryW(wszAdvpack);
    pExtractFilesA = (void *)GetProcAddress(advpack, "ExtractFiles");

    /* FIXME: Use unicode version (not yet implemented) */
    file_name_a = heap_strdupWtoA(file_name);
    hres = pExtractFilesA(file_name_a, install_dir, 0, NULL, NULL, 0);
    FreeLibrary(advpack);
    heap_free(file_name_a);
    if(FAILED(hres)) {
        ERR("Could not extract package: %08x\n", hres);
        clean_up();
        return FALSE;
    }

    set_registry(install_dir);
    clean_up();

    return TRUE;
}

static BOOL install_from_unix_file(const char *file_name)
{
    LPWSTR dos_file_name;
    int fd;
    BOOL ret;

    static WCHAR * (CDECL *wine_get_dos_file_name)(const char*);
    static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};

    fd = open(file_name, O_RDONLY);
    if(fd == -1) {
        TRACE("%s not found\n", debugstr_a(file_name));
        return FALSE;
    }

    close(fd);

    if(!wine_get_dos_file_name)
        wine_get_dos_file_name = (void*)GetProcAddress(GetModuleHandleW(kernel32W), "wine_get_dos_file_name");

    if(wine_get_dos_file_name) { /* Wine UNIX mode */
	dos_file_name = wine_get_dos_file_name(file_name);
	if(!dos_file_name) {
	    ERR("Could not get dos file name of %s\n", debugstr_a(file_name));
	    return FALSE;
	}
    } else { /* Windows mode */
	UINT res;
	WARN("Could not get wine_get_dos_file_name function, calling install_cab directly.\n");
	res = MultiByteToWideChar( CP_ACP, 0, file_name, -1, 0, 0);
	dos_file_name = heap_alloc (res*sizeof(WCHAR));
	MultiByteToWideChar( CP_ACP, 0, file_name, -1, dos_file_name, res);
    }

    ret = install_cab(dos_file_name);

    heap_free(dos_file_name);
    return ret;
}

static BOOL install_from_registered_dir(void)
{
    char *file_name;
    HKEY hkey;
    DWORD res, type, size = MAX_PATH;
    BOOL ret;

    /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */
    res = RegOpenKeyW(HKEY_CURRENT_USER, mshtml_keyW, &hkey);
    if(res != ERROR_SUCCESS)
        return FALSE;

    file_name = heap_alloc(size+sizeof(GECKO_FILE_NAME));
    res = RegGetValueA(hkey, NULL, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size);
    if(res == ERROR_MORE_DATA) {
        file_name = heap_realloc(file_name, size+sizeof(GECKO_FILE_NAME));
        res = RegGetValueA(hkey, NULL, "GeckoCabDir", RRF_RT_ANY, &type, (PBYTE)file_name, &size);
    }
    RegCloseKey(hkey);
    if(res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) {
        heap_free(file_name);
        return FALSE;
    }

    strcat(file_name, GECKO_FILE_NAME);

    TRACE("Trying %s\n", debugstr_a(file_name));

    ret = install_from_unix_file(file_name);

    heap_free(file_name);
    return ret;
}

static BOOL install_from_default_dir(void)
{
    const char *data_dir, *subdir;
    char *file_name;
    int len, len2;
    BOOL ret;

    if((data_dir = wine_get_data_dir()))
        subdir = "/gecko/";
    else if((data_dir = wine_get_build_dir()))
        subdir = "/../gecko/";
    else
        return FALSE;

    len = strlen(data_dir);
    len2 = strlen(subdir);

    file_name = heap_alloc(len+len2+sizeof(GECKO_FILE_NAME));
    memcpy(file_name, data_dir, len);
    memcpy(file_name+len, subdir, len2);
    memcpy(file_name+len+len2, GECKO_FILE_NAME, sizeof(GECKO_FILE_NAME));

    ret = install_from_unix_file(file_name);

    heap_free(file_name);

    if (!ret)
        ret = install_from_unix_file( GECKO_DATADIR "/wine/gecko/" GECKO_FILE_NAME);
    if (!ret && strcmp( GECKO_DATADIR, "/usr/share" ))
        ret = install_from_unix_file("/usr/share/wine/gecko/" GECKO_FILE_NAME);
    return ret;
}

static HRESULT WINAPI InstallCallback_QueryInterface(IBindStatusCallback *iface,
                                                     REFIID riid, void **ppv)
{
    if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IBindStatusCallback, riid)) {
        *ppv = iface;
        return S_OK;
    }

    return E_INVALIDARG;
}

static ULONG WINAPI InstallCallback_AddRef(IBindStatusCallback *iface)
{
    return 2;
}

static ULONG WINAPI InstallCallback_Release(IBindStatusCallback *iface)
{
    return 1;
}

static HRESULT WINAPI InstallCallback_OnStartBinding(IBindStatusCallback *iface,
        DWORD dwReserved, IBinding *pib)
{
    WCHAR tmp_dir[MAX_PATH];

    set_status(IDS_DOWNLOADING);

    GetTempPathW(sizeof(tmp_dir)/sizeof(WCHAR), tmp_dir);

    tmp_file_name = heap_alloc(MAX_PATH*sizeof(WCHAR));
    GetTempFileNameW(tmp_dir, NULL, 0, tmp_file_name);

    TRACE("creating temp file %s\n", debugstr_w(tmp_file_name));

    tmp_file = CreateFileW(tmp_file_name, GENERIC_WRITE, 0, NULL, 
                           CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if(tmp_file == INVALID_HANDLE_VALUE) {
        ERR("Could not create file: %d\n", GetLastError());
        clean_up();
        return E_FAIL;
    }

    return S_OK;
}

static HRESULT WINAPI InstallCallback_GetPriority(IBindStatusCallback *iface,
        LONG *pnPriority)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallCallback_OnLowResource(IBindStatusCallback *iface,
       DWORD dwReserved)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI InstallCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
        ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
    HWND progress = GetDlgItem(install_dialog, ID_DWL_PROGRESS);

    if(ulProgressMax)
        SendMessageW(progress, PBM_SETRANGE32, 0, ulProgressMax);
    if(ulProgress)
        SendMessageW(progress, PBM_SETPOS, ulProgress, 0);

    return S_OK;
}

static HRESULT WINAPI InstallCallback_OnStopBinding(IBindStatusCallback *iface,
        HRESULT hresult, LPCWSTR szError)
{
    if(FAILED(hresult)) {
        ERR("Binding failed %08x\n", hresult);
        clean_up();
        return S_OK;
    }

    CloseHandle(tmp_file);
    tmp_file = INVALID_HANDLE_VALUE;

    set_status(IDS_INSTALLING);

    install_cab(tmp_file_name);

    return S_OK;
}

static HRESULT WINAPI InstallCallback_GetBindInfo(IBindStatusCallback *iface,
        DWORD* grfBINDF, BINDINFO* pbindinfo)
{
    /* FIXME */
    *grfBINDF = 0;
    return S_OK;
}

static HRESULT WINAPI InstallCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
        DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
{
    IStream *str = pstgmed->u.pstm;
    BYTE buf[1024];
    DWORD size;
    HRESULT hres;

    do {
        DWORD written;

        size = 0;
        hres = IStream_Read(str, buf, sizeof(buf), &size);
        if(size)
            WriteFile(tmp_file, buf, size, &written, NULL);
    }while(hres == S_OK);

    return S_OK;
}

static HRESULT WINAPI InstallCallback_OnObjectAvailable(IBindStatusCallback *iface,
        REFIID riid, IUnknown* punk)
{
    ERR("\n");
    return E_NOTIMPL;
}

static const IBindStatusCallbackVtbl InstallCallbackVtbl = {
    InstallCallback_QueryInterface,
    InstallCallback_AddRef,
    InstallCallback_Release,
    InstallCallback_OnStartBinding,
    InstallCallback_GetPriority,
    InstallCallback_OnLowResource,
    InstallCallback_OnProgress,
    InstallCallback_OnStopBinding,
    InstallCallback_GetBindInfo,
    InstallCallback_OnDataAvailable,
    InstallCallback_OnObjectAvailable
};

static IBindStatusCallback InstallCallback = { &InstallCallbackVtbl };

static LPWSTR get_url(void)
{
    HKEY hkey;
    DWORD res, type;
    DWORD size = INTERNET_MAX_URL_LENGTH*sizeof(WCHAR);
    DWORD returned_size;
    LPWSTR url;

    static const WCHAR wszGeckoUrl[] = {'G','e','c','k','o','U','r','l',0};
    static const WCHAR httpW[] = {'h','t','t','p'};
    static const WCHAR arch_formatW[] = {'?','a','r','c','h','='};
    static const WCHAR v_formatW[] = {'&','v','='};

    /* @@ Wine registry key: HKCU\Software\Wine\MSHTML */
    res = RegOpenKeyW(HKEY_CURRENT_USER, mshtml_keyW, &hkey);
    if(res != ERROR_SUCCESS)
        return NULL;

    url = heap_alloc(size);
    returned_size = size;

    res = RegQueryValueExW(hkey, wszGeckoUrl, NULL, &type, (LPBYTE)url, &returned_size);
    RegCloseKey(hkey);
    if(res != ERROR_SUCCESS || type != REG_SZ) {
        heap_free(url);
        return NULL;
    }

    if(returned_size > sizeof(httpW) && !memcmp(url, httpW, sizeof(httpW))) {
        DWORD len;

        len = strlenW(url);
        memcpy(url+len, arch_formatW, sizeof(arch_formatW));
        len += sizeof(arch_formatW)/sizeof(WCHAR);
        len += MultiByteToWideChar(CP_ACP, 0, GECKO_ARCH, sizeof(GECKO_ARCH), url+len, size/sizeof(WCHAR)-len)-1;
        memcpy(url+len, v_formatW, sizeof(v_formatW));
        len += sizeof(v_formatW)/sizeof(WCHAR);
        MultiByteToWideChar(CP_ACP, 0, GECKO_VERSION, -1, url+len, size/sizeof(WCHAR)-len);
    }

    TRACE("Got URL %s\n", debugstr_w(url));
    return url;
}

static DWORD WINAPI download_proc(PVOID arg)
{
    IMoniker *mon;
    IBindCtx *bctx;
    IStream *str = NULL;
    HRESULT hres;

    CreateURLMoniker(NULL, url, &mon);
    heap_free(url);
    url = NULL;

    CreateAsyncBindCtx(0, &InstallCallback, 0, &bctx);

    hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&str);
    IBindCtx_Release(bctx);
    if(FAILED(hres)) {
        ERR("BindToStorage failed: %08x\n", hres);
        return 0;
    }

    if(str)
        IStream_Release(str);

    return 0;
}

static INT_PTR CALLBACK installer_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg) {
    case WM_INITDIALOG:
        ShowWindow(GetDlgItem(hwnd, ID_DWL_PROGRESS), SW_HIDE);
        install_dialog = hwnd;
        return TRUE;

    case WM_COMMAND:
        switch(wParam) {
        case IDCANCEL:
            EndDialog(hwnd, 0);
            return FALSE;

        case ID_DWL_INSTALL:
            ShowWindow(GetDlgItem(hwnd, ID_DWL_PROGRESS), SW_SHOW);
            EnableWindow(GetDlgItem(hwnd, ID_DWL_INSTALL), 0);
            EnableWindow(GetDlgItem(hwnd, IDCANCEL), 0); /* FIXME */
            CreateThread(NULL, 0, download_proc, NULL, 0, NULL);
            return FALSE;
        }
    }

    return FALSE;
}

BOOL install_wine_gecko(BOOL silent)
{
    HANDLE hsem;

    if(!*GECKO_ARCH)
        return FALSE;

    SetLastError(ERROR_SUCCESS);
    hsem = CreateSemaphoreA( NULL, 0, 1, "mshtml_install_semaphore");

    if(GetLastError() == ERROR_ALREADY_EXISTS) {
        WaitForSingleObject(hsem, INFINITE);
    }else {
        /*
         * Try to find Gecko .cab file in following order:
         * - directory stored in GeckoCabDir value of HKCU/Software/MSHTML key
         * - $datadir/gecko
         * - download from URL stored in GeckoUrl value of HKCU/Software/MSHTML key
         */
        if(!install_from_registered_dir()
           && !install_from_default_dir()
           && !silent && (url = get_url()))
            DialogBoxW(hInst, MAKEINTRESOURCEW(ID_DWL_DIALOG), 0, installer_proc);
    }

    ReleaseSemaphore(hsem, 1, NULL);
    CloseHandle(hsem);

    return TRUE;
}
