/*
 * Copyright 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 "hlink_private.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(hlink);

typedef struct {
    IUnknown           IUnknown_inner;
    IAuthenticate      IAuthenticate_iface;
    IHttpNegotiate     IHttpNegotiate_iface;
    IExtensionServices IExtensionServices_iface;

    IUnknown *outer_unk;
    LONG ref;

    HWND hwnd;
    LPWSTR username;
    LPWSTR password;
    LPWSTR headers;
} ExtensionService;

static inline ExtensionService *impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, ExtensionService, IUnknown_inner);
}

static HRESULT WINAPI ExtServUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
    ExtensionService *This = impl_from_IUnknown(iface);

    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IUnknown_inner;
    }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
        TRACE("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
        *ppv = &This->IAuthenticate_iface;
    }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
        TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This, ppv);
        *ppv = &This->IHttpNegotiate_iface;
    }else if(IsEqualGUID(&IID_IExtensionServices, riid)) {
        TRACE("(%p)->(IID_IExtensionServices %p)\n", This, ppv);
        *ppv = &This->IExtensionServices_iface;
    }

    if(*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }

    FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
    return E_NOINTERFACE;
}

static ULONG WINAPI ExtServUnk_AddRef(IUnknown *iface)
{
    ExtensionService *This = impl_from_IUnknown(iface);
    LONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI ExtServUnk_Release(IUnknown *iface)
{
    ExtensionService *This = impl_from_IUnknown(iface);
    LONG ref = InterlockedDecrement(&This->ref);

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

    if(!ref) {
        heap_free(This->username);
        heap_free(This->password);
        heap_free(This->headers);
        heap_free(This);
    }

    return ref;
}

static const IUnknownVtbl ExtServUnkVtbl = {
    ExtServUnk_QueryInterface,
    ExtServUnk_AddRef,
    ExtServUnk_Release
};

static inline ExtensionService *impl_from_IAuthenticate(IAuthenticate *iface)
{
    return CONTAINING_RECORD(iface, ExtensionService, IAuthenticate_iface);
}

static HRESULT WINAPI Authenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
{
    ExtensionService *This = impl_from_IAuthenticate(iface);
    return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}

static ULONG WINAPI Authenticate_AddRef(IAuthenticate *iface)
{
    ExtensionService *This = impl_from_IAuthenticate(iface);
    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI Authenticate_Release(IAuthenticate *iface)
{
    ExtensionService *This = impl_from_IAuthenticate(iface);
    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI Authenticate_Authenticate(IAuthenticate *iface,
        HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
{
    ExtensionService *This = impl_from_IAuthenticate(iface);

    TRACE("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);

    if(!phwnd || !pszUsername || !pszPassword)
        return E_INVALIDARG;

    *phwnd = This->hwnd;
    *pszUsername = hlink_co_strdupW(This->username);
    *pszPassword = hlink_co_strdupW(This->password);

    return S_OK;
}

static const IAuthenticateVtbl AuthenticateVtbl = {
    Authenticate_QueryInterface,
    Authenticate_AddRef,
    Authenticate_Release,
    Authenticate_Authenticate
};

static inline ExtensionService *impl_from_IHttpNegotiate(IHttpNegotiate *iface)
{
    return CONTAINING_RECORD(iface, ExtensionService, IHttpNegotiate_iface);
}

static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface, REFIID riid, void **ppv)
{
    ExtensionService *This = impl_from_IHttpNegotiate(iface);
    return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}

static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate *iface)
{
    ExtensionService *This = impl_from_IHttpNegotiate(iface);
    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate *iface)
{
    ExtensionService *This = impl_from_IHttpNegotiate(iface);
    return IUnknown_Release(This->outer_unk);
}

static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate *iface,
        LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
{
    ExtensionService *This = impl_from_IHttpNegotiate(iface);

    TRACE("(%p)->(%s %s %x %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved,
          pszAdditionalHeaders);

    if(!pszAdditionalHeaders)
        return E_INVALIDARG;

    *pszAdditionalHeaders = hlink_co_strdupW(This->headers);
    return S_OK;
}

static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate *iface, DWORD dwResponseCode,
        LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
{
    ExtensionService *This = impl_from_IHttpNegotiate(iface);

    TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
          debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);

    *pszAdditionalRequestHeaders = NULL;
    return S_OK;
}

static const IHttpNegotiateVtbl HttpNegotiateVtbl = {
    HttpNegotiate_QueryInterface,
    HttpNegotiate_AddRef,
    HttpNegotiate_Release,
    HttpNegotiate_BeginningTransaction,
    HttpNegotiate_OnResponse
};

static inline ExtensionService *impl_from_IExtensionServices(IExtensionServices *iface)
{
    return CONTAINING_RECORD(iface, ExtensionService, IExtensionServices_iface);
}

static HRESULT WINAPI ExtServ_QueryInterface(IExtensionServices *iface, REFIID riid, void **ppv)
{
    ExtensionService *This = impl_from_IExtensionServices(iface);
    return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}

static ULONG WINAPI ExtServ_AddRef(IExtensionServices *iface)
{
    ExtensionService *This = impl_from_IExtensionServices(iface);
    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI ExtServ_Release(IExtensionServices *iface)
{
    ExtensionService *This = impl_from_IExtensionServices(iface);
    return IUnknown_Release(This->outer_unk);
}

static HRESULT ExtServ_ImplSetAdditionalHeaders(ExtensionService* This, LPCWSTR pwzAdditionalHeaders)
{
    int len;

    heap_free(This->headers);
    This->headers = NULL;

    if (!pwzAdditionalHeaders)
        return S_OK;

    len = strlenW(pwzAdditionalHeaders);

    if(len && pwzAdditionalHeaders[len-1] != '\n' && pwzAdditionalHeaders[len-1] != '\r') {
        static const WCHAR endlW[] = {'\r','\n',0};
        This->headers = heap_alloc(len*sizeof(WCHAR) + sizeof(endlW));
        memcpy(This->headers, pwzAdditionalHeaders, len*sizeof(WCHAR));
        memcpy(This->headers+len, endlW, sizeof(endlW));
    }else {
        This->headers = hlink_strdupW(pwzAdditionalHeaders);
    }

    return S_OK;
}

static HRESULT WINAPI ExtServ_SetAdditionalHeaders(IExtensionServices* iface, LPCWSTR pwzAdditionalHeaders)
{
    ExtensionService *This = impl_from_IExtensionServices(iface);

    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzAdditionalHeaders));

    return ExtServ_ImplSetAdditionalHeaders(This,pwzAdditionalHeaders);
}

static HRESULT ExtServ_ImplSetAuthenticateData(ExtensionService* This, HWND phwnd, LPCWSTR pwzUsername, LPCWSTR pwzPassword)
{
    heap_free(This->username);
    heap_free(This->password);

    This->hwnd = phwnd;
    This->username = hlink_strdupW(pwzUsername);
    This->password = hlink_strdupW(pwzPassword);

    return S_OK;
}

static HRESULT WINAPI ExtServ_SetAuthenticateData(IExtensionServices* iface, HWND phwnd, LPCWSTR pwzUsername, LPCWSTR pwzPassword)
{
    ExtensionService *This = impl_from_IExtensionServices(iface);

    TRACE("(%p)->(%p %s %s)\n", This, phwnd, debugstr_w(pwzUsername), debugstr_w(pwzPassword));

    return ExtServ_ImplSetAuthenticateData(This, phwnd, pwzUsername, pwzPassword);
}

static const IExtensionServicesVtbl ExtServVtbl = {
    ExtServ_QueryInterface,
    ExtServ_AddRef,
    ExtServ_Release,
    ExtServ_SetAdditionalHeaders,
    ExtServ_SetAuthenticateData
};

/***********************************************************************
 *             HlinkCreateExtensionServices (HLINK.@)
 */
HRESULT WINAPI HlinkCreateExtensionServices(LPCWSTR pwzAdditionalHeaders,
        HWND phwnd, LPCWSTR pszUsername, LPCWSTR pszPassword,
        IUnknown *punkOuter, REFIID riid, void** ppv)
{
    ExtensionService *ret;
    HRESULT hres = S_OK;

    TRACE("%s %p %s %s %p %s %p\n",debugstr_w(pwzAdditionalHeaders),
            phwnd, debugstr_w(pszUsername), debugstr_w(pszPassword),
            punkOuter, debugstr_guid(riid), ppv);

    ret = heap_alloc(sizeof(*ret));

    ret->IUnknown_inner.lpVtbl = &ExtServUnkVtbl;
    ret->IAuthenticate_iface.lpVtbl = &AuthenticateVtbl;
    ret->IHttpNegotiate_iface.lpVtbl = &HttpNegotiateVtbl;
    ret->IExtensionServices_iface.lpVtbl = &ExtServVtbl;
    ret->ref = 1;
    ret->headers = NULL;
    ret->hwnd = NULL;
    ret->username = NULL;
    ret->password = NULL;

    ExtServ_ImplSetAuthenticateData(ret, phwnd, pszUsername, pszPassword);
    ExtServ_ImplSetAdditionalHeaders(ret, pwzAdditionalHeaders);

    if(!punkOuter) {
        ret->outer_unk = &ret->IUnknown_inner;
        hres = IUnknown_QueryInterface(&ret->IUnknown_inner, riid, ppv);
        IUnknown_Release(&ret->IUnknown_inner);
    }else if(IsEqualGUID(&IID_IUnknown, riid)) {
        ret->outer_unk = punkOuter;
        *ppv = &ret->IUnknown_inner;
    }else {
        IUnknown_Release(&ret->IUnknown_inner);
        hres = E_INVALIDARG;
    }

    return hres;
}
