/*
 * Queue Manager (BITS) File
 *
 * Copyright 2007, 2008 Google (Roy Shea, Dan Hipschman)
 *
 * 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 <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "ole2.h"
#include "urlmon.h"
#include "wininet.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(qmgr);

static void BackgroundCopyFileDestructor(BackgroundCopyFileImpl *This)
{
    IBackgroundCopyJob_Release((IBackgroundCopyJob *) This->owner);
    HeapFree(GetProcessHeap(), 0, This->info.LocalName);
    HeapFree(GetProcessHeap(), 0, This->info.RemoteName);
    HeapFree(GetProcessHeap(), 0, This);
}

static ULONG WINAPI BITS_IBackgroundCopyFile_AddRef(IBackgroundCopyFile* iface)
{
    BackgroundCopyFileImpl *This = (BackgroundCopyFileImpl *) iface;
    return InterlockedIncrement(&This->ref);
}

static HRESULT WINAPI BITS_IBackgroundCopyFile_QueryInterface(
    IBackgroundCopyFile* iface,
    REFIID riid,
    void **ppvObject)
{
    BackgroundCopyFileImpl *This = (BackgroundCopyFileImpl *) iface;

    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IBackgroundCopyFile))
    {
        *ppvObject = &This->lpVtbl;
        BITS_IBackgroundCopyFile_AddRef(iface);
        return S_OK;
    }

    *ppvObject = NULL;
    return E_NOINTERFACE;
}


static ULONG WINAPI BITS_IBackgroundCopyFile_Release(
    IBackgroundCopyFile* iface)
{
    BackgroundCopyFileImpl *This = (BackgroundCopyFileImpl *) iface;
    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
        BackgroundCopyFileDestructor(This);

    return ref;
}

/* Get the remote name of a background copy file */
static HRESULT WINAPI BITS_IBackgroundCopyFile_GetRemoteName(
    IBackgroundCopyFile* iface,
    LPWSTR *pVal)
{
    BackgroundCopyFileImpl *This = (BackgroundCopyFileImpl *) iface;
    int n = (lstrlenW(This->info.RemoteName) + 1) * sizeof(WCHAR);

    *pVal = CoTaskMemAlloc(n);
    if (!*pVal)
        return E_OUTOFMEMORY;

    memcpy(*pVal, This->info.RemoteName, n);
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyFile_GetLocalName(
    IBackgroundCopyFile* iface,
    LPWSTR *pVal)
{
    BackgroundCopyFileImpl *This = (BackgroundCopyFileImpl *) iface;
    int n = (lstrlenW(This->info.LocalName) + 1) * sizeof(WCHAR);

    *pVal = CoTaskMemAlloc(n);
    if (!*pVal)
        return E_OUTOFMEMORY;

    memcpy(*pVal, This->info.LocalName, n);
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyFile_GetProgress(
    IBackgroundCopyFile* iface,
    BG_FILE_PROGRESS *pVal)
{
    BackgroundCopyFileImpl *This = (BackgroundCopyFileImpl *) iface;

    EnterCriticalSection(&This->owner->cs);
    pVal->BytesTotal = This->fileProgress.BytesTotal;
    pVal->BytesTransferred = This->fileProgress.BytesTransferred;
    pVal->Completed = This->fileProgress.Completed;
    LeaveCriticalSection(&This->owner->cs);

    return S_OK;
}

static const IBackgroundCopyFileVtbl BITS_IBackgroundCopyFile_Vtbl =
{
    BITS_IBackgroundCopyFile_QueryInterface,
    BITS_IBackgroundCopyFile_AddRef,
    BITS_IBackgroundCopyFile_Release,
    BITS_IBackgroundCopyFile_GetRemoteName,
    BITS_IBackgroundCopyFile_GetLocalName,
    BITS_IBackgroundCopyFile_GetProgress
};

HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner,
                                      LPCWSTR remoteName, LPCWSTR localName,
                                      LPVOID *ppObj)
{
    BackgroundCopyFileImpl *This;
    int n;

    TRACE("(%s,%s,%p)\n", debugstr_w(remoteName),
            debugstr_w(localName), ppObj);

    This = HeapAlloc(GetProcessHeap(), 0, sizeof *This);
    if (!This)
        return E_OUTOFMEMORY;

    n = (lstrlenW(remoteName) + 1) * sizeof(WCHAR);
    This->info.RemoteName = HeapAlloc(GetProcessHeap(), 0, n);
    if (!This->info.RemoteName)
    {
        HeapFree(GetProcessHeap(), 0, This);
        return E_OUTOFMEMORY;
    }
    memcpy(This->info.RemoteName, remoteName, n);

    n = (lstrlenW(localName) + 1) * sizeof(WCHAR);
    This->info.LocalName = HeapAlloc(GetProcessHeap(), 0, n);
    if (!This->info.LocalName)
    {
        HeapFree(GetProcessHeap(), 0, This->info.RemoteName);
        HeapFree(GetProcessHeap(), 0, This);
        return E_OUTOFMEMORY;
    }
    memcpy(This->info.LocalName, localName, n);

    This->lpVtbl = &BITS_IBackgroundCopyFile_Vtbl;
    This->ref = 1;

    This->fileProgress.BytesTotal = BG_SIZE_UNKNOWN;
    This->fileProgress.BytesTransferred = 0;
    This->fileProgress.Completed = FALSE;
    This->owner = owner;
    IBackgroundCopyJob_AddRef((IBackgroundCopyJob *) owner);

    *ppObj = &This->lpVtbl;
    return S_OK;
}

static DWORD CALLBACK copyProgressCallback(LARGE_INTEGER totalSize,
                                           LARGE_INTEGER totalTransferred,
                                           LARGE_INTEGER streamSize,
                                           LARGE_INTEGER streamTransferred,
                                           DWORD streamNum,
                                           DWORD reason,
                                           HANDLE srcFile,
                                           HANDLE dstFile,
                                           LPVOID obj)
{
    BackgroundCopyFileImpl *file = (BackgroundCopyFileImpl *) obj;
    BackgroundCopyJobImpl *job = file->owner;
    ULONG64 diff;

    EnterCriticalSection(&job->cs);
    diff = (file->fileProgress.BytesTotal == BG_SIZE_UNKNOWN
            ? totalTransferred.QuadPart
            : totalTransferred.QuadPart - file->fileProgress.BytesTransferred);
    file->fileProgress.BytesTotal = totalSize.QuadPart;
    file->fileProgress.BytesTransferred = totalTransferred.QuadPart;
    job->jobProgress.BytesTransferred += diff;
    LeaveCriticalSection(&job->cs);

    return (job->state == BG_JOB_STATE_TRANSFERRING
            ? PROGRESS_CONTINUE
            : PROGRESS_CANCEL);
}

typedef struct
{
    const IBindStatusCallbackVtbl *lpVtbl;
    BackgroundCopyFileImpl *file;
    LONG ref;
} DLBindStatusCallback;

static ULONG WINAPI DLBindStatusCallback_AddRef(IBindStatusCallback *iface)
{
    DLBindStatusCallback *This = (DLBindStatusCallback *) iface;
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI DLBindStatusCallback_Release(IBindStatusCallback *iface)
{
    DLBindStatusCallback *This = (DLBindStatusCallback *) iface;
    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
    {
        IBackgroundCopyFile_Release((IBackgroundCopyFile *) This->file);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI DLBindStatusCallback_QueryInterface(
    IBindStatusCallback *iface,
    REFIID riid,
    void **ppvObject)
{
    DLBindStatusCallback *This = (DLBindStatusCallback *) iface;

    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IBindStatusCallback))
    {
        *ppvObject = &This->lpVtbl;
        DLBindStatusCallback_AddRef(iface);
        return S_OK;
    }

    *ppvObject = NULL;
    return E_NOINTERFACE;
}

static HRESULT WINAPI DLBindStatusCallback_GetBindInfo(
    IBindStatusCallback *iface,
    DWORD *grfBINDF,
    BINDINFO *pbindinfo)
{
    return E_NOTIMPL;
}

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

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

static HRESULT WINAPI DLBindStatusCallback_OnLowResource(
    IBindStatusCallback *iface,
    DWORD reserved)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI DLBindStatusCallback_OnObjectAvailable(
    IBindStatusCallback *iface,
    REFIID riid,
    IUnknown *punk)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI DLBindStatusCallback_OnProgress(
    IBindStatusCallback *iface,
    ULONG progress,
    ULONG progressMax,
    ULONG statusCode,
    LPCWSTR statusText)
{
    DLBindStatusCallback *This = (DLBindStatusCallback *) iface;
    BackgroundCopyFileImpl *file = This->file;
    BackgroundCopyJobImpl *job = file->owner;
    ULONG64 diff;

    EnterCriticalSection(&job->cs);
    diff = (file->fileProgress.BytesTotal == BG_SIZE_UNKNOWN
            ? progress
            : progress - file->fileProgress.BytesTransferred);
    file->fileProgress.BytesTotal = progressMax ? progressMax : BG_SIZE_UNKNOWN;
    file->fileProgress.BytesTransferred = progress;
    job->jobProgress.BytesTransferred += diff;
    LeaveCriticalSection(&job->cs);

    return S_OK;
}

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

static HRESULT WINAPI DLBindStatusCallback_OnStopBinding(
    IBindStatusCallback *iface,
    HRESULT hresult,
    LPCWSTR szError)
{
    return E_NOTIMPL;
}

static const IBindStatusCallbackVtbl DLBindStatusCallback_Vtbl =
{
    DLBindStatusCallback_QueryInterface,
    DLBindStatusCallback_AddRef,
    DLBindStatusCallback_Release,
    DLBindStatusCallback_OnStartBinding,
    DLBindStatusCallback_GetPriority,
    DLBindStatusCallback_OnLowResource,
    DLBindStatusCallback_OnProgress,
    DLBindStatusCallback_OnStopBinding,
    DLBindStatusCallback_GetBindInfo,
    DLBindStatusCallback_OnDataAvailable,
    DLBindStatusCallback_OnObjectAvailable
};

static DLBindStatusCallback *DLBindStatusCallbackConstructor(
    BackgroundCopyFileImpl *file)
{
    DLBindStatusCallback *This = HeapAlloc(GetProcessHeap(), 0, sizeof *This);
    if (!This)
        return NULL;

    This->lpVtbl = &DLBindStatusCallback_Vtbl;
    IBackgroundCopyFile_AddRef((IBackgroundCopyFile *) file);
    This->file = file;
    This->ref = 1;
    return This;
}

BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
{
    static const WCHAR prefix[] = {'B','I','T', 0};
    IBindStatusCallback *callbackObj;
    WCHAR tmpDir[MAX_PATH];
    WCHAR tmpName[MAX_PATH];
    HRESULT hr;

    if (!GetTempPathW(MAX_PATH, tmpDir))
    {
        ERR("Couldn't create temp file name: %d\n", GetLastError());
        /* Guessing on what state this should give us */
        transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSIENT_ERROR);
        return FALSE;
    }

    if (!GetTempFileNameW(tmpDir, prefix, 0, tmpName))
    {
        ERR("Couldn't create temp file: %d\n", GetLastError());
        /* Guessing on what state this should give us */
        transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSIENT_ERROR);
        return FALSE;
    }

    callbackObj = (IBindStatusCallback *) DLBindStatusCallbackConstructor(file);
    if (!callbackObj)
    {
        ERR("Out of memory\n");
        transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSIENT_ERROR);
        return FALSE;
    }

    EnterCriticalSection(&job->cs);
    file->fileProgress.BytesTotal = BG_SIZE_UNKNOWN;
    file->fileProgress.BytesTransferred = 0;
    file->fileProgress.Completed = FALSE;
    LeaveCriticalSection(&job->cs);

    TRACE("Transferring: %s -> %s -> %s\n",
          debugstr_w(file->info.RemoteName),
          debugstr_w(tmpName),
          debugstr_w(file->info.LocalName));

    transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRING);

    DeleteUrlCacheEntryW(file->info.RemoteName);
    hr = URLDownloadToFileW(NULL, file->info.RemoteName, tmpName, 0, callbackObj);
    IBindStatusCallback_Release(callbackObj);
    if (hr == INET_E_DOWNLOAD_FAILURE)
    {
        TRACE("URLDownload failed, trying local file copy\n");
        if (!CopyFileExW(file->info.RemoteName, tmpName, copyProgressCallback,
                         file, NULL, 0))
        {
            ERR("Local file copy failed: error %d\n", GetLastError());
            transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
            return FALSE;
        }
    }
    else if (!SUCCEEDED(hr))
    {
        ERR("URLDownload failed: eh 0x%08x\n", hr);
        transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
        return FALSE;
    }

    if (transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_QUEUED))
    {
        lstrcpyW(file->tempFileName, tmpName);

        EnterCriticalSection(&job->cs);
        file->fileProgress.Completed = TRUE;
        job->jobProgress.FilesTransferred++;
        LeaveCriticalSection(&job->cs);

        return TRUE;
    }
    else
    {
        DeleteFileW(tmpName);
        return FALSE;
    }
}
