/*
 * Copyright 2009 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 <stdio.h>
#include <assert.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "activscp.h"

#include "wine/debug.h"

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

static const WCHAR about_blankW[] = {'a','b','o','u','t',':','b','l','a','n','k',0};

/* Defined as extern in urlmon.idl, but not exported by uuid.lib */
DECLSPEC_HIDDEN const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
    {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};

static inline HTMLDocumentNode *impl_from_IInternetHostSecurityManager(IInternetHostSecurityManager *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocumentNode, IInternetHostSecurityManager_iface);
}

static HRESULT WINAPI InternetHostSecurityManager_QueryInterface(IInternetHostSecurityManager *iface, REFIID riid, void **ppv)
{
    HTMLDocumentNode *This = impl_from_IInternetHostSecurityManager(iface);
    return IHTMLDOMNode_QueryInterface(&This->node.IHTMLDOMNode_iface, riid, ppv);
}

static ULONG WINAPI InternetHostSecurityManager_AddRef(IInternetHostSecurityManager *iface)
{
    HTMLDocumentNode *This = impl_from_IInternetHostSecurityManager(iface);
    return IHTMLDOMNode_AddRef(&This->node.IHTMLDOMNode_iface);
}

static ULONG WINAPI InternetHostSecurityManager_Release(IInternetHostSecurityManager *iface)
{
    HTMLDocumentNode *This = impl_from_IInternetHostSecurityManager(iface);
    return IHTMLDOMNode_Release(&This->node.IHTMLDOMNode_iface);
}

static HRESULT WINAPI InternetHostSecurityManager_GetSecurityId(IInternetHostSecurityManager *iface,  BYTE *pbSecurityId,
        DWORD *pcbSecurityId, DWORD_PTR dwReserved)
{
    HTMLDocumentNode *This = impl_from_IInternetHostSecurityManager(iface);
    FIXME("(%p)->(%p %p %lx)\n", This, pbSecurityId, pcbSecurityId, dwReserved);
    return E_NOTIMPL;
}

static HRESULT WINAPI InternetHostSecurityManager_ProcessUrlAction(IInternetHostSecurityManager *iface, DWORD dwAction,
        BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved)
{
    HTMLDocumentNode *This = impl_from_IInternetHostSecurityManager(iface);
    const WCHAR *url;

    TRACE("(%p)->(%d %p %d %p %d %x %x)\n", This, dwAction, pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved);

    if(!This->basedoc.window)
        return E_UNEXPECTED;

    url = This->basedoc.window->url ? This->basedoc.window->url : about_blankW;

    return IInternetSecurityManager_ProcessUrlAction(This->basedoc.window->secmgr, url, dwAction, pPolicy, cbPolicy,
            pContext, cbContext, dwFlags, dwReserved);
}

static HRESULT confirm_safety_load(HTMLDocumentNode *This, struct CONFIRMSAFETY *cs, DWORD *ret)
{
    IObjectSafety *obj_safety;
    HRESULT hres;

    hres = IUnknown_QueryInterface(cs->pUnk, &IID_IObjectSafety, (void**)&obj_safety);
    if(SUCCEEDED(hres)) {
        hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatch,
                INTERFACESAFE_FOR_UNTRUSTED_DATA, INTERFACESAFE_FOR_UNTRUSTED_DATA);
        IObjectSafety_Release(obj_safety);
        *ret = SUCCEEDED(hres) ? URLPOLICY_ALLOW : URLPOLICY_DISALLOW;
    }else {
        CATID init_catid = CATID_SafeForInitializing;

        hres = ICatInformation_IsClassOfCategories(This->catmgr, &cs->clsid, 1, &init_catid, 0, NULL);
        assert(SUCCEEDED(hres));
        *ret = hres == S_OK ? URLPOLICY_ALLOW : URLPOLICY_DISALLOW;
    }

    return S_OK;
}

static HRESULT confirm_safety(HTMLDocumentNode *This, const WCHAR *url, struct CONFIRMSAFETY *cs, DWORD *ret)
{
    DWORD policy, enabled_opts, supported_opts;
    IObjectSafety *obj_safety;
    HRESULT hres;

    TRACE("%s %p %s\n", debugstr_w(url), cs->pUnk, debugstr_guid(&cs->clsid));

    /* FIXME: Check URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY */

    hres = IInternetSecurityManager_ProcessUrlAction(This->basedoc.window->secmgr, url, URLACTION_SCRIPT_SAFE_ACTIVEX,
            (BYTE*)&policy, sizeof(policy), NULL, 0, 0, 0);
    if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
        *ret = URLPOLICY_DISALLOW;
        return S_OK;
    }

    hres = IUnknown_QueryInterface(cs->pUnk, &IID_IObjectSafety, (void**)&obj_safety);
    if(SUCCEEDED(hres)) {
        hres = IObjectSafety_GetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, &supported_opts, &enabled_opts);
        if(FAILED(hres))
            supported_opts = 0;

        enabled_opts = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
        if(supported_opts & INTERFACE_USES_SECURITY_MANAGER)
            enabled_opts |= INTERFACE_USES_SECURITY_MANAGER;

        hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatchEx, enabled_opts, enabled_opts);
        if(FAILED(hres)) {
            enabled_opts &= ~INTERFACE_USES_SECURITY_MANAGER;
            hres = IObjectSafety_SetInterfaceSafetyOptions(obj_safety, &IID_IDispatch, enabled_opts, enabled_opts);
        }
        IObjectSafety_Release(obj_safety);

        if(FAILED(hres)) {
            *ret = URLPOLICY_DISALLOW;
            return S_OK;
        }
    }else {
        CATID scripting_catid = CATID_SafeForScripting;

        if(!This->catmgr) {
            hres = CoCreateInstance(&CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER,
                    &IID_ICatInformation, (void**)&This->catmgr);
            if(FAILED(hres))
                return hres;
        }

        hres = ICatInformation_IsClassOfCategories(This->catmgr, &cs->clsid, 1, &scripting_catid, 0, NULL);
        if(FAILED(hres))
            return hres;

        if(hres != S_OK) {
            *ret = URLPOLICY_DISALLOW;
            return S_OK;
        }
    }

    if(cs->dwFlags & CONFIRMSAFETYACTION_LOADOBJECT)
        return confirm_safety_load(This, cs, ret);

    *ret = URLPOLICY_ALLOW;
    return S_OK;
}

static HRESULT WINAPI InternetHostSecurityManager_QueryCustomPolicy(IInternetHostSecurityManager *iface, REFGUID guidKey,
        BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwReserved)
{
    HTMLDocumentNode *This = impl_from_IInternetHostSecurityManager(iface);
    const WCHAR *url;
    HRESULT hres;

    TRACE("(%p)->(%s %p %p %p %d %x)\n", This, debugstr_guid(guidKey), ppPolicy, pcbPolicy, pContext, cbContext, dwReserved);

    if(!This->basedoc.window)
        return E_UNEXPECTED;

    url = This->basedoc.window->url ? This->basedoc.window->url : about_blankW;

    hres = IInternetSecurityManager_QueryCustomPolicy(This->basedoc.window->secmgr, url, guidKey, ppPolicy, pcbPolicy,
            pContext, cbContext, dwReserved);
    if(hres != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
        return hres;

    if(IsEqualGUID(&GUID_CUSTOM_CONFIRMOBJECTSAFETY, guidKey)) {
        IActiveScript *active_script;
        struct CONFIRMSAFETY *cs;
        DWORD policy;

        if(cbContext != sizeof(struct CONFIRMSAFETY)) {
            FIXME("wrong context size\n");
            return E_FAIL;
        }

        cs = (struct CONFIRMSAFETY*)pContext;
        TRACE("cs = {%s %p %x}\n", debugstr_guid(&cs->clsid), cs->pUnk, cs->dwFlags);

        hres = IUnknown_QueryInterface(cs->pUnk, &IID_IActiveScript, (void**)&active_script);
        if(SUCCEEDED(hres)) {
            FIXME("Got IAciveScript iface\n");
            IActiveScript_Release(active_script);
            return E_FAIL;
        }

        hres = confirm_safety(This, url, cs, &policy);
        if(FAILED(hres))
            return hres;

        *ppPolicy = CoTaskMemAlloc(sizeof(policy));
        if(!*ppPolicy)
            return E_OUTOFMEMORY;

        *(DWORD*)*ppPolicy = policy;
        *pcbPolicy = sizeof(policy);
        TRACE("policy %x\n", policy);
        return S_OK;
    }

    FIXME("Unknown guidKey %s\n", debugstr_guid(guidKey));
    return hres;
}

static const IInternetHostSecurityManagerVtbl InternetHostSecurityManagerVtbl = {
    InternetHostSecurityManager_QueryInterface,
    InternetHostSecurityManager_AddRef,
    InternetHostSecurityManager_Release,
    InternetHostSecurityManager_GetSecurityId,
    InternetHostSecurityManager_ProcessUrlAction,
    InternetHostSecurityManager_QueryCustomPolicy
};

void HTMLDocumentNode_SecMgr_Init(HTMLDocumentNode *This)
{
    This->IInternetHostSecurityManager_iface.lpVtbl = &InternetHostSecurityManagerVtbl;
}
