/* OLE DB Row Position library
 *
 * Copyright 2013 Nikolay Sivov
 *
 * 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
 */

#define COBJMACROS

#include "windef.h"
#include "ole2.h"
#include "olectl.h"

#include "oledb.h"
#include "oledberr.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(oledb);

typedef struct rowpos rowpos;
typedef struct
{
    IConnectionPoint IConnectionPoint_iface;
    rowpos *container;
    IRowPositionChange **sinks;
    DWORD sinks_size;
} rowpos_cp;

struct rowpos
{
    IRowPosition IRowPosition_iface;
    IConnectionPointContainer IConnectionPointContainer_iface;
    LONG ref;

    IRowset *rowset;
    IChapteredRowset *chrst;
    HROW row;
    HCHAPTER chapter;
    DBPOSITIONFLAGS flags;
    BOOL cleared;
    rowpos_cp cp;
};

static void rowposchange_cp_destroy(rowpos_cp*);

static inline rowpos *impl_from_IRowPosition(IRowPosition *iface)
{
    return CONTAINING_RECORD(iface, rowpos, IRowPosition_iface);
}

static inline rowpos *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
{
    return CONTAINING_RECORD(iface, rowpos, IConnectionPointContainer_iface);
}

static inline rowpos_cp *impl_from_IConnectionPoint(IConnectionPoint *iface)
{
    return CONTAINING_RECORD(iface, rowpos_cp, IConnectionPoint_iface);
}

static HRESULT rowpos_fireevent(rowpos *rp, DBREASON reason, DBEVENTPHASE phase)
{
    BOOL cant_deny = phase == DBEVENTPHASE_FAILEDTODO || phase == DBEVENTPHASE_SYNCHAFTER;
    HRESULT hr = S_OK;
    DWORD i;

    for (i = 0; i < rp->cp.sinks_size; i++)
        if (rp->cp.sinks[i])
        {
            hr = IRowPositionChange_OnRowPositionChange(rp->cp.sinks[i], reason, phase, cant_deny);
            if (phase == DBEVENTPHASE_FAILEDTODO) return DB_E_CANCELED;
            if (hr != S_OK) return hr;
        }

    return hr;
}

static void rowpos_clearposition(rowpos *rp)
{
    if (!rp->cleared)
    {
        if (rp->rowset)
            IRowset_ReleaseRows(rp->rowset, 1, &rp->row, NULL, NULL, NULL);
        if (rp->chrst)
            IChapteredRowset_ReleaseChapter(rp->chrst, rp->chapter, NULL);
    }

    rp->row = DB_NULL_HROW;
    rp->chapter = DB_NULL_HCHAPTER;
    rp->flags = DBPOSITION_NOROW;
}

static HRESULT WINAPI rowpos_QueryInterface(IRowPosition* iface, REFIID riid, void **obj)
{
    rowpos *This = impl_from_IRowPosition(iface);

    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IRowPosition))
    {
        *obj = iface;
    }
    else if (IsEqualIID(riid, &IID_IConnectionPointContainer))
    {
        *obj = &This->IConnectionPointContainer_iface;
    }
    else
    {
        FIXME("interface %s not implemented\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IRowPosition_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI rowpos_AddRef(IRowPosition* iface)
{
    rowpos *This = impl_from_IRowPosition(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI rowpos_Release(IRowPosition* iface)
{
    rowpos *This = impl_from_IRowPosition(iface);
    LONG ref = InterlockedDecrement(&This->ref);

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

    if (ref == 0)
    {
        if (This->rowset) IRowset_Release(This->rowset);
        if (This->chrst) IChapteredRowset_Release(This->chrst);
        rowposchange_cp_destroy(&This->cp);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI rowpos_ClearRowPosition(IRowPosition* iface)
{
    rowpos *This = impl_from_IRowPosition(iface);
    HRESULT hr;

    TRACE("(%p)\n", This);

    if (!This->rowset) return E_UNEXPECTED;

    hr = rowpos_fireevent(This, DBREASON_ROWPOSITION_CLEARED, DBEVENTPHASE_OKTODO);
    if (hr != S_OK)
        return rowpos_fireevent(This, DBREASON_ROWPOSITION_CLEARED, DBEVENTPHASE_FAILEDTODO);

    hr = rowpos_fireevent(This, DBREASON_ROWPOSITION_CLEARED, DBEVENTPHASE_ABOUTTODO);
    if (hr != S_OK)
        return rowpos_fireevent(This, DBREASON_ROWPOSITION_CLEARED, DBEVENTPHASE_FAILEDTODO);

    rowpos_clearposition(This);
    This->cleared = TRUE;
    return S_OK;
}

static HRESULT WINAPI rowpos_GetRowPosition(IRowPosition *iface, HCHAPTER *chapter,
    HROW *row, DBPOSITIONFLAGS *flags)
{
    rowpos *This = impl_from_IRowPosition(iface);

    TRACE("(%p)->(%p %p %p)\n", This, chapter, row, flags);

    *chapter = This->chapter;
    *row = This->row;
    *flags = This->flags;

    if (!This->rowset) return E_UNEXPECTED;

    return S_OK;
}

static HRESULT WINAPI rowpos_GetRowset(IRowPosition *iface, REFIID riid, IUnknown **rowset)
{
    rowpos *This = impl_from_IRowPosition(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), rowset);

    if (!This->rowset) return E_UNEXPECTED;
    return IRowset_QueryInterface(This->rowset, riid, (void**)rowset);
}

static HRESULT WINAPI rowpos_Initialize(IRowPosition *iface, IUnknown *rowset)
{
    rowpos *This = impl_from_IRowPosition(iface);
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, rowset);

    if (This->rowset) return DB_E_ALREADYINITIALIZED;

    hr = IUnknown_QueryInterface(rowset, &IID_IRowset, (void**)&This->rowset);
    if (FAILED(hr)) return hr;

    /* this one is optional */
    IUnknown_QueryInterface(rowset, &IID_IChapteredRowset, (void**)&This->chrst);
    return S_OK;
}

static HRESULT WINAPI rowpos_SetRowPosition(IRowPosition *iface, HCHAPTER chapter,
    HROW row, DBPOSITIONFLAGS flags)
{
    rowpos *This = impl_from_IRowPosition(iface);
    DBREASON reason;
    HRESULT hr;

    TRACE("(%p)->(%lx %lx %d)\n", This, chapter, row, flags);

    if (!This->cleared) return E_UNEXPECTED;

    hr = IRowset_AddRefRows(This->rowset, 1, &row, NULL, NULL);
    if (FAILED(hr)) return hr;

    if (This->chrst)
    {
        hr = IChapteredRowset_AddRefChapter(This->chrst, chapter, NULL);
        if (FAILED(hr))
        {
            IRowset_ReleaseRows(This->rowset, 1, &row, NULL, NULL, NULL);
            return hr;
        }
    }

    reason = This->chrst ? DBREASON_ROWPOSITION_CHAPTERCHANGED : DBREASON_ROWPOSITION_CHANGED;
    hr = rowpos_fireevent(This, reason, DBEVENTPHASE_SYNCHAFTER);
    if (hr != S_OK)
    {
        IRowset_ReleaseRows(This->rowset, 1, &row, NULL, NULL, NULL);
        if (This->chrst)
            IChapteredRowset_ReleaseChapter(This->chrst, chapter, NULL);
        return rowpos_fireevent(This, reason, DBEVENTPHASE_FAILEDTODO);
    }
    else
        rowpos_fireevent(This, reason, DBEVENTPHASE_DIDEVENT);

    /* previously set chapter and row are released with ClearRowPosition() */
    This->chapter = chapter;
    This->row = row;
    This->flags = flags;
    This->cleared = FALSE;

    return S_OK;
}

static const struct IRowPositionVtbl rowpos_vtbl =
{
    rowpos_QueryInterface,
    rowpos_AddRef,
    rowpos_Release,
    rowpos_ClearRowPosition,
    rowpos_GetRowPosition,
    rowpos_GetRowset,
    rowpos_Initialize,
    rowpos_SetRowPosition
};

static HRESULT WINAPI cpc_QueryInterface(IConnectionPointContainer *iface, REFIID riid, void **obj)
{
    rowpos *This = impl_from_IConnectionPointContainer(iface);
    return IRowPosition_QueryInterface(&This->IRowPosition_iface, riid, obj);
}

static ULONG WINAPI cpc_AddRef(IConnectionPointContainer *iface)
{
    rowpos *This = impl_from_IConnectionPointContainer(iface);
    return IRowPosition_AddRef(&This->IRowPosition_iface);
}

static ULONG WINAPI cpc_Release(IConnectionPointContainer *iface)
{
    rowpos *This = impl_from_IConnectionPointContainer(iface);
    return IRowPosition_Release(&This->IRowPosition_iface);
}

static HRESULT WINAPI cpc_EnumConnectionPoints(IConnectionPointContainer *iface, IEnumConnectionPoints **enum_points)
{
    rowpos *This = impl_from_IConnectionPointContainer(iface);
    FIXME("(%p)->(%p): stub\n", This, enum_points);
    return E_NOTIMPL;
}

static HRESULT WINAPI cpc_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid, IConnectionPoint **point)
{
    rowpos *This = impl_from_IConnectionPointContainer(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), point);

    if (IsEqualIID(riid, &IID_IRowPositionChange))
    {
        *point = &This->cp.IConnectionPoint_iface;
        IConnectionPoint_AddRef(*point);
        return S_OK;
    }
    else
    {
        FIXME("unsupported riid %s\n", debugstr_guid(riid));
        return CONNECT_E_NOCONNECTION;
    }
}

static const struct IConnectionPointContainerVtbl rowpos_cpc_vtbl =
{
    cpc_QueryInterface,
    cpc_AddRef,
    cpc_Release,
    cpc_EnumConnectionPoints,
    cpc_FindConnectionPoint
};

static HRESULT WINAPI rowpos_cp_QueryInterface(IConnectionPoint *iface, REFIID riid, void **obj)
{
    rowpos_cp *This = impl_from_IConnectionPoint(iface);
    return IConnectionPointContainer_QueryInterface(&This->container->IConnectionPointContainer_iface, riid, obj);
}

static ULONG WINAPI rowpos_cp_AddRef(IConnectionPoint *iface)
{
    rowpos_cp *This = impl_from_IConnectionPoint(iface);
    return IConnectionPointContainer_AddRef(&This->container->IConnectionPointContainer_iface);
}

static ULONG WINAPI rowpos_cp_Release(IConnectionPoint *iface)
{
    rowpos_cp *This = impl_from_IConnectionPoint(iface);
    return IConnectionPointContainer_Release(&This->container->IConnectionPointContainer_iface);
}

static HRESULT WINAPI rowpos_cp_GetConnectionInterface(IConnectionPoint *iface, IID *iid)
{
    rowpos_cp *This = impl_from_IConnectionPoint(iface);

    TRACE("(%p)->(%p)\n", This, iid);

    if (!iid) return E_POINTER;

    *iid = IID_IRowPositionChange;
    return S_OK;
}

static HRESULT WINAPI rowpos_cp_GetConnectionPointContainer(IConnectionPoint *iface, IConnectionPointContainer **container)
{
    rowpos_cp *This = impl_from_IConnectionPoint(iface);

    TRACE("(%p)->(%p)\n", This, container);

    if (!container) return E_POINTER;

    *container = &This->container->IConnectionPointContainer_iface;
    IConnectionPointContainer_AddRef(*container);
    return S_OK;
}

static HRESULT WINAPI rowpos_cp_Advise(IConnectionPoint *iface, IUnknown *unksink, DWORD *cookie)
{
    rowpos_cp *This = impl_from_IConnectionPoint(iface);
    IRowPositionChange *sink;
    HRESULT hr;
    DWORD i;

    TRACE("(%p)->(%p %p)\n", This, unksink, cookie);

    if (!cookie) return E_POINTER;

    hr = IUnknown_QueryInterface(unksink, &IID_IRowPositionChange, (void**)&sink);
    if (FAILED(hr))
    {
        FIXME("sink doesn't support IRowPositionChange\n");
        return CONNECT_E_CANNOTCONNECT;
    }

    if (This->sinks)
    {
        for (i = 0; i < This->sinks_size; i++)
        {
            if (!This->sinks[i])
                break;
        }

        if (i == This->sinks_size)
        {
            This->sinks_size *= 2;
            This->sinks = heap_realloc_zero(This->sinks, This->sinks_size*sizeof(*This->sinks));
        }
    }
    else
    {
        This->sinks_size = 10;
        This->sinks = heap_alloc_zero(This->sinks_size*sizeof(*This->sinks));
        i = 0;
    }

    This->sinks[i] = sink;
    if (cookie) *cookie = i + 1;

    return S_OK;
}

static HRESULT WINAPI rowpos_cp_Unadvise(IConnectionPoint *iface, DWORD cookie)
{
    rowpos_cp *This = impl_from_IConnectionPoint(iface);

    TRACE("(%p)->(%d)\n", This, cookie);

    if (!cookie || cookie > This->sinks_size || !This->sinks[cookie-1])
        return CONNECT_E_NOCONNECTION;

    IRowPositionChange_Release(This->sinks[cookie-1]);
    This->sinks[cookie-1] = NULL;

    return S_OK;
}

static HRESULT WINAPI rowpos_cp_EnumConnections(IConnectionPoint *iface, IEnumConnections **enum_c)
{
    rowpos_cp *This = impl_from_IConnectionPoint(iface);
    FIXME("(%p)->(%p): stub\n", This, enum_c);
    return E_NOTIMPL;
}

static const struct IConnectionPointVtbl rowpos_cp_vtbl =
{
    rowpos_cp_QueryInterface,
    rowpos_cp_AddRef,
    rowpos_cp_Release,
    rowpos_cp_GetConnectionInterface,
    rowpos_cp_GetConnectionPointContainer,
    rowpos_cp_Advise,
    rowpos_cp_Unadvise,
    rowpos_cp_EnumConnections
};

static void rowposchange_cp_init(rowpos_cp *cp, rowpos *container)
{
    cp->IConnectionPoint_iface.lpVtbl = &rowpos_cp_vtbl;
    cp->container = container;
    cp->sinks = NULL;
    cp->sinks_size = 0;
}

void rowposchange_cp_destroy(rowpos_cp *cp)
{
    DWORD i;
    for (i = 0; i < cp->sinks_size; i++)
    {
        if (cp->sinks[i])
            IRowPositionChange_Release(cp->sinks[i]);
    }
    heap_free(cp->sinks);
}

HRESULT create_oledb_rowpos(IUnknown *outer, void **obj)
{
    rowpos *This;

    TRACE("(%p, %p)\n", outer, obj);

    *obj = NULL;

    if(outer) return CLASS_E_NOAGGREGATION;

    This = heap_alloc(sizeof(*This));
    if(!This) return E_OUTOFMEMORY;

    This->IRowPosition_iface.lpVtbl = &rowpos_vtbl;
    This->IConnectionPointContainer_iface.lpVtbl = &rowpos_cpc_vtbl;
    This->ref = 1;
    This->rowset = NULL;
    This->chrst = NULL;
    This->cleared = FALSE;
    rowpos_clearposition(This);
    rowposchange_cp_init(&This->cp, This);

    *obj = &This->IRowPosition_iface;

    return S_OK;
}
