/*
 * Implementation of scripting for Microsoft Installer (msi.dll)
 *
 * Copyright 2007 Misha Koshelev
 *
 * 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
 */

#define COBJMACROS

#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winuser.h"
#include "msidefs.h"
#include "msipriv.h"
#include "activscp.h"
#include "oleauto.h"
#include "wine/debug.h"
#include "wine/unicode.h"

#include "msiserver.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);

#ifdef _WIN64

#define IActiveScriptParse_Release IActiveScriptParse64_Release
#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText

#else

#define IActiveScriptParse_Release IActiveScriptParse32_Release
#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText

#endif

static const WCHAR szJScript[] = { 'J','S','c','r','i','p','t',0};
static const WCHAR szVBScript[] = { 'V','B','S','c','r','i','p','t',0};
static const WCHAR szSession[] = {'S','e','s','s','i','o','n',0};

/*
 * MsiActiveScriptSite - Our IActiveScriptSite implementation.
 */
typedef struct {
    IActiveScriptSite IActiveScriptSite_iface;
    IDispatch *installer;
    IDispatch *session;
    LONG ref;
} MsiActiveScriptSite;

static inline MsiActiveScriptSite *impl_from_IActiveScriptSite( IActiveScriptSite *iface )
{
    return CONTAINING_RECORD(iface, MsiActiveScriptSite, IActiveScriptSite_iface);
}

/*
 * MsiActiveScriptSite
 */
static HRESULT WINAPI MsiActiveScriptSite_QueryInterface(IActiveScriptSite* iface, REFIID riid, void** obj)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);

    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);

    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IActiveScriptSite))
    {
        IActiveScriptSite_AddRef(iface);
        *obj = iface;
        return S_OK;
    }

    *obj = NULL;

    return E_NOINTERFACE;
}

static ULONG WINAPI MsiActiveScriptSite_AddRef(IActiveScriptSite* iface)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI MsiActiveScriptSite_Release(IActiveScriptSite* iface)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
        msi_free(This);

    return ref;
}

static HRESULT WINAPI MsiActiveScriptSite_GetLCID(IActiveScriptSite* iface, LCID* plcid)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);
    TRACE("(%p)->(%p)\n", This, plcid);
    return E_NOTIMPL;  /* Script will use system-defined locale */
}

static HRESULT WINAPI MsiActiveScriptSite_GetItemInfo(IActiveScriptSite* iface, LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppiunkItem, ITypeInfo** ppti)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);

    TRACE("(%p)->(%p, %d, %p, %p)\n", This, pstrName, dwReturnMask, ppiunkItem, ppti);

    /* Determine the kind of pointer that is requested, and make sure placeholder is valid */
    if (dwReturnMask & SCRIPTINFO_ITYPEINFO) {
        if (!ppti) return E_INVALIDARG;
        *ppti = NULL;
    }
    if (dwReturnMask & SCRIPTINFO_IUNKNOWN) {
        if (!ppiunkItem) return E_INVALIDARG;
        *ppiunkItem = NULL;
    }

    /* Are we looking for the session object? */
    if (!strcmpW(szSession, pstrName)) {
        if (dwReturnMask & SCRIPTINFO_ITYPEINFO) {
            HRESULT hr = get_typeinfo(Session_tid, ppti);
            if (SUCCEEDED(hr))
                ITypeInfo_AddRef(*ppti);
            return hr;
        }
        else if (dwReturnMask & SCRIPTINFO_IUNKNOWN) {
            IDispatch_QueryInterface(This->session, &IID_IUnknown, (void **)ppiunkItem);
            return S_OK;
        }
    }

    return TYPE_E_ELEMENTNOTFOUND;
}

static HRESULT WINAPI MsiActiveScriptSite_GetDocVersionString(IActiveScriptSite* iface, BSTR* pbstrVersion)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);
    TRACE("(%p)->(%p)\n", This, pbstrVersion);
    return E_NOTIMPL;
}

static HRESULT WINAPI MsiActiveScriptSite_OnScriptTerminate(IActiveScriptSite* iface, const VARIANT* pvarResult, const EXCEPINFO* pexcepinfo)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);
    TRACE("(%p)->(%p, %p)\n", This, pvarResult, pexcepinfo);
    return S_OK;
}

static HRESULT WINAPI MsiActiveScriptSite_OnStateChange(IActiveScriptSite* iface, SCRIPTSTATE ssScriptState)
{
    switch (ssScriptState) {
        case SCRIPTSTATE_UNINITIALIZED:
              TRACE("State: Uninitialized.\n");
              break;

        case SCRIPTSTATE_INITIALIZED:
              TRACE("State: Initialized.\n");
              break;

        case SCRIPTSTATE_STARTED:
              TRACE("State: Started.\n");
              break;

        case SCRIPTSTATE_CONNECTED:
              TRACE("State: Connected.\n");
              break;

        case SCRIPTSTATE_DISCONNECTED:
              TRACE("State: Disconnected.\n");
              break;

        case SCRIPTSTATE_CLOSED:
              TRACE("State: Closed.\n");
              break;

        default:
              ERR("Unknown State: %d\n", ssScriptState);
              break;
    }

    return S_OK;
}

static HRESULT WINAPI MsiActiveScriptSite_OnScriptError(IActiveScriptSite* iface, IActiveScriptError* pscripterror)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);
    EXCEPINFO exception;
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, pscripterror);

    memset(&exception, 0, sizeof(EXCEPINFO));
    hr = IActiveScriptError_GetExceptionInfo(pscripterror, &exception);
    if (SUCCEEDED(hr))
    {
        ERR("script error: %s\n", debugstr_w(exception.bstrDescription));
        SysFreeString(exception.bstrSource);
        SysFreeString(exception.bstrDescription);
        SysFreeString(exception.bstrHelpFile);
    }

    return S_OK;
}

static HRESULT WINAPI MsiActiveScriptSite_OnEnterScript(IActiveScriptSite* iface)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);
    TRACE("(%p)\n", This);
    return S_OK;
}

static HRESULT WINAPI MsiActiveScriptSite_OnLeaveScript(IActiveScriptSite* iface)
{
    MsiActiveScriptSite *This = impl_from_IActiveScriptSite(iface);
    TRACE("(%p)\n", This);
    return S_OK;
}

static const struct IActiveScriptSiteVtbl activescriptsitevtbl =
{
    MsiActiveScriptSite_QueryInterface,
    MsiActiveScriptSite_AddRef,
    MsiActiveScriptSite_Release,
    MsiActiveScriptSite_GetLCID,
    MsiActiveScriptSite_GetItemInfo,
    MsiActiveScriptSite_GetDocVersionString,
    MsiActiveScriptSite_OnScriptTerminate,
    MsiActiveScriptSite_OnStateChange,
    MsiActiveScriptSite_OnScriptError,
    MsiActiveScriptSite_OnEnterScript,
    MsiActiveScriptSite_OnLeaveScript
};

static HRESULT create_activescriptsite(MsiActiveScriptSite **obj)
{
    MsiActiveScriptSite* object;

    TRACE("(%p)\n", obj);

    *obj = NULL;

    object = msi_alloc( sizeof(MsiActiveScriptSite) );
    if (!object)
        return E_OUTOFMEMORY;

    object->IActiveScriptSite_iface.lpVtbl = &activescriptsitevtbl;
    object->ref = 1;
    object->installer = NULL;
    object->session = NULL;

    *obj = object;

    return S_OK;
}

static UINT map_return_value(LONG val)
{
    switch (val)
    {
    case 0:
    case IDOK:
    case IDIGNORE:  return ERROR_SUCCESS;
    case IDCANCEL:  return ERROR_INSTALL_USEREXIT;
    case IDRETRY:   return ERROR_INSTALL_SUSPEND;
    case IDABORT:
    default:        return ERROR_INSTALL_FAILURE;
    }
}

/*
 * Call a script.
 */
DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action)
{
    HRESULT hr;
    IActiveScript *pActiveScript = NULL;
    IActiveScriptParse *pActiveScriptParse = NULL;
    MsiActiveScriptSite *scriptsite;
    IDispatch *pDispatch = NULL;
    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
    DISPID dispid;
    CLSID clsid;
    VARIANT var;
    DWORD ret = ERROR_INSTALL_FAILURE;

    CoInitialize(NULL);

    /* Create MsiActiveScriptSite object */
    hr = create_activescriptsite(&scriptsite);
    if (hr != S_OK) goto done;

    /* Create an installer object */
    hr = create_msiserver(NULL, (void**)&scriptsite->installer);
    if (hr != S_OK) goto done;

    /* Create a session object */
    hr = create_session(hPackage, scriptsite->installer, &scriptsite->session);
    if (hr != S_OK) goto done;

    /* Create the scripting engine */
    type &= msidbCustomActionTypeJScript|msidbCustomActionTypeVBScript;
    if (type == msidbCustomActionTypeJScript)
        hr = CLSIDFromProgID(szJScript, &clsid);
    else if (type == msidbCustomActionTypeVBScript)
        hr = CLSIDFromProgID(szVBScript, &clsid);
    else {
        ERR("Unknown script type %d\n", type);
        goto done;
    }
    if (FAILED(hr)) {
        ERR("Could not find CLSID for Windows Script\n");
        goto done;
    }
    hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IActiveScript, (void **)&pActiveScript);
    if (FAILED(hr)) {
        ERR("Could not instantiate class for Windows Script\n");
        goto done;
    }

    hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse, (void **)&pActiveScriptParse);
    if (FAILED(hr)) goto done;

    hr = IActiveScript_SetScriptSite(pActiveScript, &scriptsite->IActiveScriptSite_iface);
    if (FAILED(hr)) goto done;

    hr = IActiveScriptParse_InitNew(pActiveScriptParse);
    if (FAILED(hr)) goto done;

    hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS|SCRIPTITEM_ISVISIBLE);
    if (FAILED(hr)) goto done;

    hr = IActiveScriptParse_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
    if (FAILED(hr)) goto done;

    hr = IActiveScript_SetScriptState(pActiveScript, SCRIPTSTATE_CONNECTED);
    if (FAILED(hr)) goto done;

    /* Call a function if necessary through the IDispatch interface */
    if (function && function[0]) {
        TRACE("Calling function %s\n", debugstr_w(function));

        hr = IActiveScript_GetScriptDispatch(pActiveScript, NULL, &pDispatch);
        if (FAILED(hr)) goto done;

        hr = IDispatch_GetIDsOfNames(pDispatch, &IID_NULL, (WCHAR **)&function, 1,LOCALE_USER_DEFAULT, &dispid);
        if (FAILED(hr)) goto done;

        hr = IDispatch_Invoke(pDispatch, dispid, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparamsNoArgs, &var, NULL, NULL);
        if (FAILED(hr)) goto done;

        hr = VariantChangeType(&var, &var, 0, VT_I4);
        if (FAILED(hr)) goto done;

        ret = map_return_value(V_I4(&var));

        VariantClear(&var);
    } else {
        /* If no function to be called, MSI behavior is to succeed */
        ret = ERROR_SUCCESS;
    }

done:

    if (pDispatch) IDispatch_Release(pDispatch);
    if (pActiveScript) IActiveScript_Release(pActiveScript);
    if (pActiveScriptParse) IActiveScriptParse_Release(pActiveScriptParse);
    if (scriptsite)
    {
        if (scriptsite->session) IDispatch_Release(scriptsite->session);
        if (scriptsite->installer) IDispatch_Release(scriptsite->installer);
        IActiveScriptSite_Release(&scriptsite->IActiveScriptSite_iface);
    }
    CoUninitialize();    /* must call even if CoInitialize failed */
    return ret;
}
