/*
 * Based on ../shell32/memorystream.c
 *
 * Copyright 1999 Juergen Schmied
 * Copyright 2003 Mike McCormack 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 "urlmon_main.h"

#include "winreg.h"
#include "winternl.h"
#include "wininet.h"
#include "shlwapi.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(urlmon);

typedef struct ProxyBindStatusCallback
{
    IBindStatusCallback IBindStatusCallback_iface;

    IBindStatusCallback *pBSC;
} ProxyBindStatusCallback;

static inline ProxyBindStatusCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
{
    return CONTAINING_RECORD(iface, ProxyBindStatusCallback, IBindStatusCallback_iface);
}

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

    *ppv = NULL;
    return E_NOINTERFACE;
}

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

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

static HRESULT WINAPI ProxyBindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
                                               IBinding *pib)
{
    ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    if(This->pBSC)
        return IBindStatusCallback_OnStartBinding(This->pBSC, dwReserved, pib);

    return S_OK;
}

static HRESULT WINAPI ProxyBindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
{
    ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    if(This->pBSC)
        return IBindStatusCallback_GetPriority(This->pBSC, pnPriority);

    return S_OK;
}

static HRESULT WINAPI ProxyBindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
{
    ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    if(This->pBSC)
        return IBindStatusCallback_OnLowResource(This->pBSC, reserved);

    return S_OK;
}

static HRESULT WINAPI ProxyBindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
                                           ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
    ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    if(This->pBSC)
        return IBindStatusCallback_OnProgress(This->pBSC, ulProgress,
                                          ulProgressMax, ulStatusCode,
                                          szStatusText);

    return S_OK;
}

static HRESULT WINAPI ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
{
    ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    if(This->pBSC)
        return IBindStatusCallback_OnStopBinding(This->pBSC, hresult, szError);

    return S_OK;
}

static HRESULT WINAPI ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
{
    ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    if(This->pBSC)
        return IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo);

    return E_INVALIDARG;
}

static HRESULT WINAPI ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
                                                              DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
{
    ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    if(This->pBSC)
        return IBindStatusCallback_OnDataAvailable(This->pBSC, grfBSCF, dwSize,
                                               pformatetc, pstgmed);

    return S_OK;
}

static HRESULT WINAPI ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
{
    ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);

    if(This->pBSC)
        return IBindStatusCallback_OnObjectAvailable(This->pBSC, riid, punk);

    return S_OK;
}

static HRESULT WINAPI BlockingBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
                                                                 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
{
    return S_OK;
}

static const IBindStatusCallbackVtbl BlockingBindStatusCallbackVtbl =
{
    ProxyBindStatusCallback_QueryInterface,
    ProxyBindStatusCallback_AddRef,
    ProxyBindStatusCallback_Release,
    ProxyBindStatusCallback_OnStartBinding,
    ProxyBindStatusCallback_GetPriority,
    ProxyBindStatusCallback_OnLowResource,
    ProxyBindStatusCallback_OnProgress,
    ProxyBindStatusCallback_OnStopBinding,
    ProxyBindStatusCallback_GetBindInfo,
    BlockingBindStatusCallback_OnDataAvailable,
    ProxyBindStatusCallback_OnObjectAvailable
};

static HRESULT WINAPI AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
{
    ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface);
    HRESULT hr = IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo);
    *grfBINDF |= BINDF_PULLDATA | BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE;
    return hr;
}

static const IBindStatusCallbackVtbl AsyncBindStatusCallbackVtbl =
{
    ProxyBindStatusCallback_QueryInterface,
    ProxyBindStatusCallback_AddRef,
    ProxyBindStatusCallback_Release,
    ProxyBindStatusCallback_OnStartBinding,
    ProxyBindStatusCallback_GetPriority,
    ProxyBindStatusCallback_OnLowResource,
    ProxyBindStatusCallback_OnProgress,
    ProxyBindStatusCallback_OnStopBinding,
    AsyncBindStatusCallback_GetBindInfo,
    ProxyBindStatusCallback_OnDataAvailable,
    ProxyBindStatusCallback_OnObjectAvailable
};

static HRESULT URLStartDownload(LPCWSTR szURL, LPSTREAM *ppStream, IBindStatusCallback *pBSC)
{
    HRESULT hr;
    IMoniker *pMoniker;
    IBindCtx *pbc;

    *ppStream = NULL;

    hr = CreateURLMoniker(NULL, szURL, &pMoniker);
    if (FAILED(hr))
        return hr;

    hr = CreateBindCtx(0, &pbc);
    if (FAILED(hr))
    {
        IMoniker_Release(pMoniker);
        return hr;
    }

    hr = RegisterBindStatusCallback(pbc, pBSC, NULL, 0);
    if (FAILED(hr))
    {
        IBindCtx_Release(pbc);
        IMoniker_Release(pMoniker);
        return hr;
    }

    hr = IMoniker_BindToStorage(pMoniker, pbc, NULL, &IID_IStream, (void **)ppStream);

    /* BindToStorage returning E_PENDING because it's asynchronous is not an error */
    if (hr == E_PENDING) hr = S_OK;

    IBindCtx_Release(pbc);
    IMoniker_Release(pMoniker);

    return hr;
}

/***********************************************************************
 *		URLOpenBlockingStreamA (URLMON.@)
 */
HRESULT WINAPI URLOpenBlockingStreamA(LPUNKNOWN pCaller, LPCSTR szURL,
                                      LPSTREAM *ppStream, DWORD dwReserved,
                                      LPBINDSTATUSCALLBACK lpfnCB)
{
    LPWSTR szURLW;
    int len;
    HRESULT hr;

    TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, szURL, ppStream, dwReserved, lpfnCB);

    if (!szURL || !ppStream)
        return E_INVALIDARG;

    len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
    szURLW = heap_alloc(len * sizeof(WCHAR));
    if (!szURLW)
    {
        *ppStream = NULL;
        return E_OUTOFMEMORY;
    }
    MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len);

    hr = URLOpenBlockingStreamW(pCaller, szURLW, ppStream, dwReserved, lpfnCB);

    heap_free(szURLW);

    return hr;
}

/***********************************************************************
 *		URLOpenBlockingStreamW (URLMON.@)
 */
HRESULT WINAPI URLOpenBlockingStreamW(LPUNKNOWN pCaller, LPCWSTR szURL,
                                      LPSTREAM *ppStream, DWORD dwReserved,
                                      LPBINDSTATUSCALLBACK lpfnCB)
{
    ProxyBindStatusCallback blocking_bsc;

    TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, debugstr_w(szURL), ppStream,
          dwReserved, lpfnCB);

    if (!szURL || !ppStream)
        return E_INVALIDARG;

    blocking_bsc.IBindStatusCallback_iface.lpVtbl = &BlockingBindStatusCallbackVtbl;
    blocking_bsc.pBSC = lpfnCB;

    return URLStartDownload(szURL, ppStream, &blocking_bsc.IBindStatusCallback_iface);
}

/***********************************************************************
 *		URLOpenStreamA (URLMON.@)
 */
HRESULT WINAPI URLOpenStreamA(LPUNKNOWN pCaller, LPCSTR szURL, DWORD dwReserved,
                              LPBINDSTATUSCALLBACK lpfnCB)
{
    LPWSTR szURLW;
    int len;
    HRESULT hr;

    TRACE("(%p, %s, 0x%x, %p)\n", pCaller, szURL, dwReserved, lpfnCB);

    if (!szURL)
        return E_INVALIDARG;

    len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0);
    szURLW = heap_alloc(len * sizeof(WCHAR));
    if (!szURLW)
        return E_OUTOFMEMORY;
    MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len);

    hr = URLOpenStreamW(pCaller, szURLW, dwReserved, lpfnCB);

    heap_free(szURLW);

    return hr;
}

/***********************************************************************
 *		URLOpenStreamW (URLMON.@)
 */
HRESULT WINAPI URLOpenStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, DWORD dwReserved,
                              LPBINDSTATUSCALLBACK lpfnCB)
{
    HRESULT hr;
    ProxyBindStatusCallback async_bsc;
    IStream *pStream;

    TRACE("(%p, %s, 0x%x, %p)\n", pCaller, debugstr_w(szURL), dwReserved,
          lpfnCB);

    if (!szURL)
        return E_INVALIDARG;

    async_bsc.IBindStatusCallback_iface.lpVtbl = &AsyncBindStatusCallbackVtbl;
    async_bsc.pBSC = lpfnCB;

    hr = URLStartDownload(szURL, &pStream, &async_bsc.IBindStatusCallback_iface);
    if (SUCCEEDED(hr) && pStream)
        IStream_Release(pStream);

    return hr;
}
