/*
 * Background Copy Job Interface for BITS
 *
 * Copyright 2007 Google (Roy Shea)
 *
 * 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>

#include "windef.h"
#include "winbase.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(qmgr);

static void BackgroundCopyJobDestructor(BackgroundCopyJobImpl *This)
{
    This->cs.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection(&This->cs);
    HeapFree(GetProcessHeap(), 0, This->displayName);
    HeapFree(GetProcessHeap(), 0, This);
}

static ULONG WINAPI BITS_IBackgroundCopyJob_AddRef(IBackgroundCopyJob2 *iface)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
    return InterlockedIncrement(&This->ref);
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_QueryInterface(
    IBackgroundCopyJob2 *iface, REFIID riid, LPVOID *ppvObject)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
    TRACE("IID: %s\n", debugstr_guid(riid));

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

    *ppvObject = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob2 *iface)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
    ULONG ref = InterlockedDecrement(&This->ref);

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

    return ref;
}

/*** IBackgroundCopyJob methods ***/

static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFileSet(
    IBackgroundCopyJob2 *iface,
    ULONG cFileCount,
    BG_FILE_INFO *pFileSet)
{
    ULONG i;
    for (i = 0; i < cFileCount; ++i)
    {
        HRESULT hr = IBackgroundCopyJob_AddFile(iface, pFileSet[i].RemoteName,
                                                pFileSet[i].LocalName);
        if (FAILED(hr))
            return hr;
    }
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile(
    IBackgroundCopyJob2 *iface,
    LPCWSTR RemoteUrl,
    LPCWSTR LocalName)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
    IBackgroundCopyFile *pFile;
    BackgroundCopyFileImpl *file;
    HRESULT res;

    /* We should return E_INVALIDARG in these cases.  */
    FIXME("Check for valid filenames and supported protocols\n");

    res = BackgroundCopyFileConstructor(This, RemoteUrl, LocalName, (LPVOID *) &pFile);
    if (res != S_OK)
        return res;

    /* Add a reference to the file to file list */
    IBackgroundCopyFile_AddRef(pFile);
    file = (BackgroundCopyFileImpl *) pFile;
    EnterCriticalSection(&This->cs);
    list_add_head(&This->files, &file->entryFromJob);
    This->jobProgress.BytesTotal = BG_SIZE_UNKNOWN;
    ++This->jobProgress.FilesTotal;
    LeaveCriticalSection(&This->cs);

    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_EnumFiles(
    IBackgroundCopyJob2 *iface,
    IEnumBackgroundCopyFiles **ppEnum)
{
    TRACE("\n");
    return EnumBackgroundCopyFilesConstructor((LPVOID *) ppEnum, iface);
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_Suspend(
    IBackgroundCopyJob2 *iface)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume(
    IBackgroundCopyJob2 *iface)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
    HRESULT rv = S_OK;

    EnterCriticalSection(&globalMgr.cs);
    if (This->state == BG_JOB_STATE_CANCELLED
        || This->state == BG_JOB_STATE_ACKNOWLEDGED)
    {
        rv = BG_E_INVALID_STATE;
    }
    else if (This->jobProgress.FilesTransferred == This->jobProgress.FilesTotal)
    {
        rv = BG_E_EMPTY;
    }
    else if (This->state != BG_JOB_STATE_CONNECTING
             && This->state != BG_JOB_STATE_TRANSFERRING)
    {
        This->state = BG_JOB_STATE_QUEUED;
        SetEvent(globalMgr.jobEvent);
    }
    LeaveCriticalSection(&globalMgr.cs);

    return rv;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_Cancel(
    IBackgroundCopyJob2 *iface)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_Complete(
    IBackgroundCopyJob2 *iface)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
    HRESULT rv = S_OK;

    EnterCriticalSection(&This->cs);

    if (This->state == BG_JOB_STATE_CANCELLED
        || This->state == BG_JOB_STATE_ACKNOWLEDGED)
    {
        rv = BG_E_INVALID_STATE;
    }
    else
    {
        BackgroundCopyFileImpl *file;
        LIST_FOR_EACH_ENTRY(file, &This->files, BackgroundCopyFileImpl, entryFromJob)
        {
            if (file->fileProgress.Completed)
            {
                if (!MoveFileExW(file->tempFileName, file->info.LocalName,
                                 (MOVEFILE_COPY_ALLOWED
                                  | MOVEFILE_REPLACE_EXISTING
                                  | MOVEFILE_WRITE_THROUGH)))
                {
                    ERR("Couldn't rename file %s -> %s\n",
                        debugstr_w(file->tempFileName),
                        debugstr_w(file->info.LocalName));
                    rv = BG_S_PARTIAL_COMPLETE;
                }
            }
            else
                rv = BG_S_PARTIAL_COMPLETE;
        }
    }

    This->state = BG_JOB_STATE_ACKNOWLEDGED;
    LeaveCriticalSection(&This->cs);

    return rv;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetId(
    IBackgroundCopyJob2 *iface,
    GUID *pVal)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
    *pVal = This->jobId;
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetType(
    IBackgroundCopyJob2 *iface,
    BG_JOB_TYPE *pVal)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;

    if (!pVal)
        return E_INVALIDARG;

    *pVal = This->type;
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProgress(
    IBackgroundCopyJob2 *iface,
    BG_JOB_PROGRESS *pVal)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;

    if (!pVal)
        return E_INVALIDARG;

    EnterCriticalSection(&This->cs);
    pVal->BytesTotal = This->jobProgress.BytesTotal;
    pVal->BytesTransferred = This->jobProgress.BytesTransferred;
    pVal->FilesTotal = This->jobProgress.FilesTotal;
    pVal->FilesTransferred = This->jobProgress.FilesTransferred;
    LeaveCriticalSection(&This->cs);

    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetTimes(
    IBackgroundCopyJob2 *iface,
    BG_JOB_TIMES *pVal)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetState(
    IBackgroundCopyJob2 *iface,
    BG_JOB_STATE *pVal)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;

    if (!pVal)
        return E_INVALIDARG;

    /* Don't think we need a critical section for this */
    *pVal = This->state;
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetError(
    IBackgroundCopyJob2 *iface,
    IBackgroundCopyError **ppError)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetOwner(
    IBackgroundCopyJob2 *iface,
    LPWSTR *pVal)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDisplayName(
    IBackgroundCopyJob2 *iface,
    LPCWSTR Val)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDisplayName(
    IBackgroundCopyJob2 *iface,
    LPWSTR *pVal)
{
    BackgroundCopyJobImpl *This = (BackgroundCopyJobImpl *) iface;
    int n;

    if (!pVal)
        return E_INVALIDARG;

    n = (lstrlenW(This->displayName) + 1) * sizeof **pVal;
    *pVal = CoTaskMemAlloc(n);
    if (*pVal == NULL)
        return E_OUTOFMEMORY;
    memcpy(*pVal, This->displayName, n);
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDescription(
    IBackgroundCopyJob2 *iface,
    LPCWSTR Val)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDescription(
    IBackgroundCopyJob2 *iface,
    LPWSTR *pVal)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetPriority(
    IBackgroundCopyJob2 *iface,
    BG_JOB_PRIORITY Val)
{
    FIXME("(%p,0x%08x) stub\n", iface, Val);
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetPriority(
    IBackgroundCopyJob2 *iface,
    BG_JOB_PRIORITY *pVal)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyFlags(
    IBackgroundCopyJob2 *iface,
    ULONG Val)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyFlags(
    IBackgroundCopyJob2 *iface,
    ULONG *pVal)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyInterface(
    IBackgroundCopyJob2 *iface,
    IUnknown *Val)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyInterface(
    IBackgroundCopyJob2 *iface,
    IUnknown **pVal)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetMinimumRetryDelay(
    IBackgroundCopyJob2 *iface,
    ULONG Seconds)
{
    FIXME("%u\n", Seconds);
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetMinimumRetryDelay(
    IBackgroundCopyJob2 *iface,
    ULONG *Seconds)
{
    FIXME("%p\n", Seconds);
    *Seconds = 30;
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNoProgressTimeout(
    IBackgroundCopyJob2 *iface,
    ULONG Seconds)
{
    FIXME("%u\n", Seconds);
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNoProgressTimeout(
    IBackgroundCopyJob2 *iface,
    ULONG *Seconds)
{
    FIXME("%p\n", Seconds);
    *Seconds = 900;
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetErrorCount(
    IBackgroundCopyJob2 *iface,
    ULONG *Errors)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetProxySettings(
    IBackgroundCopyJob2 *iface,
    BG_JOB_PROXY_USAGE ProxyUsage,
    const WCHAR *ProxyList,
    const WCHAR *ProxyBypassList)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProxySettings(
    IBackgroundCopyJob2 *iface,
    BG_JOB_PROXY_USAGE *pProxyUsage,
    LPWSTR *pProxyList,
    LPWSTR *pProxyBypassList)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_TakeOwnership(
    IBackgroundCopyJob2 *iface)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyCmdLine(
    IBackgroundCopyJob2 *iface,
    LPCWSTR prog,
    LPCWSTR params)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyCmdLine(
    IBackgroundCopyJob2 *iface,
    LPWSTR *prog,
    LPWSTR *params)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyProgress(
    IBackgroundCopyJob2 *iface,
    BG_JOB_REPLY_PROGRESS *progress)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyData(
    IBackgroundCopyJob2 *iface,
    byte **pBuffer,
    UINT64 *pLength)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetReplyFileName(
    IBackgroundCopyJob2 *iface,
    LPCWSTR filename)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyFileName(
    IBackgroundCopyJob2 *iface,
    LPWSTR *pFilename)
{
    FIXME("Not implemented\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_SetCredentials(
    IBackgroundCopyJob2 *iface,
    BG_AUTH_CREDENTIALS *cred)
{
    FIXME("Not implemented\n");
    return S_OK;
}

static HRESULT WINAPI BITS_IBackgroundCopyJob_RemoveCredentials(
    IBackgroundCopyJob2 *iface,
    BG_AUTH_TARGET target,
    BG_AUTH_SCHEME scheme)
{
    FIXME("Not implemented\n");
    return S_OK;
}

static const IBackgroundCopyJob2Vtbl BITS_IBackgroundCopyJob_Vtbl =
{
    BITS_IBackgroundCopyJob_QueryInterface,
    BITS_IBackgroundCopyJob_AddRef,
    BITS_IBackgroundCopyJob_Release,
    BITS_IBackgroundCopyJob_AddFileSet,
    BITS_IBackgroundCopyJob_AddFile,
    BITS_IBackgroundCopyJob_EnumFiles,
    BITS_IBackgroundCopyJob_Suspend,
    BITS_IBackgroundCopyJob_Resume,
    BITS_IBackgroundCopyJob_Cancel,
    BITS_IBackgroundCopyJob_Complete,
    BITS_IBackgroundCopyJob_GetId,
    BITS_IBackgroundCopyJob_GetType,
    BITS_IBackgroundCopyJob_GetProgress,
    BITS_IBackgroundCopyJob_GetTimes,
    BITS_IBackgroundCopyJob_GetState,
    BITS_IBackgroundCopyJob_GetError,
    BITS_IBackgroundCopyJob_GetOwner,
    BITS_IBackgroundCopyJob_SetDisplayName,
    BITS_IBackgroundCopyJob_GetDisplayName,
    BITS_IBackgroundCopyJob_SetDescription,
    BITS_IBackgroundCopyJob_GetDescription,
    BITS_IBackgroundCopyJob_SetPriority,
    BITS_IBackgroundCopyJob_GetPriority,
    BITS_IBackgroundCopyJob_SetNotifyFlags,
    BITS_IBackgroundCopyJob_GetNotifyFlags,
    BITS_IBackgroundCopyJob_SetNotifyInterface,
    BITS_IBackgroundCopyJob_GetNotifyInterface,
    BITS_IBackgroundCopyJob_SetMinimumRetryDelay,
    BITS_IBackgroundCopyJob_GetMinimumRetryDelay,
    BITS_IBackgroundCopyJob_SetNoProgressTimeout,
    BITS_IBackgroundCopyJob_GetNoProgressTimeout,
    BITS_IBackgroundCopyJob_GetErrorCount,
    BITS_IBackgroundCopyJob_SetProxySettings,
    BITS_IBackgroundCopyJob_GetProxySettings,
    BITS_IBackgroundCopyJob_TakeOwnership,
    BITS_IBackgroundCopyJob_SetNotifyCmdLine,
    BITS_IBackgroundCopyJob_GetNotifyCmdLine,
    BITS_IBackgroundCopyJob_GetReplyProgress,
    BITS_IBackgroundCopyJob_GetReplyData,
    BITS_IBackgroundCopyJob_SetReplyFileName,
    BITS_IBackgroundCopyJob_GetReplyFileName,
    BITS_IBackgroundCopyJob_SetCredentials,
    BITS_IBackgroundCopyJob_RemoveCredentials
};

HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type,
                                     GUID *pJobId, LPVOID *ppObj)
{
    HRESULT hr;
    BackgroundCopyJobImpl *This;
    int n;

    TRACE("(%s,%d,%p)\n", debugstr_w(displayName), type, ppObj);

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

    This->lpVtbl = &BITS_IBackgroundCopyJob_Vtbl;
    InitializeCriticalSection(&This->cs);
    This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BackgroundCopyJobImpl.cs");

    This->ref = 1;
    This->type = type;

    n = (lstrlenW(displayName) + 1) *  sizeof *displayName;
    This->displayName = HeapAlloc(GetProcessHeap(), 0, n);
    if (!This->displayName)
    {
        This->cs.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->cs);
        HeapFree(GetProcessHeap(), 0, This);
        return E_OUTOFMEMORY;
    }
    memcpy(This->displayName, displayName, n);

    hr = CoCreateGuid(&This->jobId);
    if (FAILED(hr))
    {
        This->cs.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->cs);
        HeapFree(GetProcessHeap(), 0, This->displayName);
        HeapFree(GetProcessHeap(), 0, This);
        return hr;
    }
    *pJobId = This->jobId;

    list_init(&This->files);
    This->jobProgress.BytesTotal = 0;
    This->jobProgress.BytesTransferred = 0;
    This->jobProgress.FilesTotal = 0;
    This->jobProgress.FilesTransferred = 0;

    This->state = BG_JOB_STATE_SUSPENDED;

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

void processJob(BackgroundCopyJobImpl *job)
{
    for (;;)
    {
        BackgroundCopyFileImpl *file;
        BOOL done = TRUE;

        EnterCriticalSection(&job->cs);
        LIST_FOR_EACH_ENTRY(file, &job->files, BackgroundCopyFileImpl, entryFromJob)
            if (!file->fileProgress.Completed)
            {
                done = FALSE;
                break;
            }
        LeaveCriticalSection(&job->cs);
        if (done)
        {
            transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRED);
            return;
        }

        if (!processFile(file, job))
          return;
    }
}
