/* OLE DB ErrorInfo
 *
 * Copyright 2013 Alistair Leslie-Hughes
 *
 * 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 <string.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "oleauto.h"
#include "winerror.h"
#include "oledb.h"
#include "oledberr.h"

#include "oledb_private.h"

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

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(oledb);

struct ErrorEntry
{
    struct list entry;
    ERRORINFO       info;
    DISPPARAMS      dispparams;
    IUnknown        *unknown;
    DWORD           lookupID;
};

typedef struct ErrorInfoImpl
{
    IErrorInfo     IErrorInfo_iface;
    IErrorRecords  IErrorRecords_iface;
    LONG ref;

    GUID m_Guid;
    BSTR source;
    BSTR description;
    BSTR help_file;
    DWORD help_context;

    struct list errors;
} ErrorInfoImpl;

static inline ErrorInfoImpl *impl_from_IErrorInfo( IErrorInfo *iface )
{
    return CONTAINING_RECORD(iface, ErrorInfoImpl, IErrorInfo_iface);
}

static inline ErrorInfoImpl *impl_from_IErrorRecords( IErrorRecords *iface )
{
    return CONTAINING_RECORD(iface, ErrorInfoImpl, IErrorRecords_iface);
}

static HRESULT WINAPI IErrorInfoImpl_QueryInterface(IErrorInfo* iface, REFIID riid, void **ppvoid)
{
    ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
    TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid),ppvoid);

    *ppvoid = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IErrorInfo))
    {
      *ppvoid = &This->IErrorInfo_iface;
    }
    else if (IsEqualIID(riid, &IID_IErrorRecords))
    {
      *ppvoid = &This->IErrorRecords_iface;
    }

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

    FIXME("interface %s not implemented\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI IErrorInfoImpl_AddRef(IErrorInfo* iface)
{
    ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
    TRACE("(%p)->%u\n",This,This->ref);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI IErrorInfoImpl_Release(IErrorInfo* iface)
{
    ErrorInfoImpl *This = impl_from_IErrorInfo(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    struct ErrorEntry *cursor, *cursor2;

    TRACE("(%p)->%u\n",This,ref+1);

    if (!ref)
    {
        SysFreeString(This->source);
        SysFreeString(This->description);
        SysFreeString(This->help_file);

        LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->errors, struct ErrorEntry, entry)
        {
            list_remove(&cursor->entry);
            if(cursor->unknown)
                IUnknown_Release(cursor->unknown);

            heap_free(cursor);
        }
        heap_free(This);
    }
    return ref;
}

static HRESULT WINAPI IErrorInfoImpl_GetGUID(IErrorInfo* iface, GUID * pGUID)
{
    ErrorInfoImpl *This = impl_from_IErrorInfo(iface);

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

    if(!pGUID )
        return E_INVALIDARG;

    *pGUID = This->m_Guid;

    return S_OK;
}

static HRESULT WINAPI IErrorInfoImpl_GetSource(IErrorInfo* iface, BSTR *pBstrSource)
{
    ErrorInfoImpl *This = impl_from_IErrorInfo(iface);

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

    if (pBstrSource == NULL)
        return E_INVALIDARG;

    *pBstrSource = SysAllocString(This->source);

    return S_OK;
}

static HRESULT WINAPI IErrorInfoImpl_GetDescription(IErrorInfo* iface, BSTR *pBstrDescription)
{
    ErrorInfoImpl *This = impl_from_IErrorInfo(iface);

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

    if (pBstrDescription == NULL)
        return E_INVALIDARG;

    *pBstrDescription = SysAllocString(This->description);

    return S_OK;
}

static HRESULT WINAPI IErrorInfoImpl_GetHelpFile(IErrorInfo* iface, BSTR *pBstrHelpFile)
{
    ErrorInfoImpl *This = impl_from_IErrorInfo(iface);

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

    if (pBstrHelpFile == NULL)
        return E_INVALIDARG;

    *pBstrHelpFile = SysAllocString(This->help_file);

    return S_OK;
}

static HRESULT WINAPI IErrorInfoImpl_GetHelpContext(IErrorInfo* iface, DWORD *pdwHelpContext)
{
    ErrorInfoImpl *This = impl_from_IErrorInfo(iface);

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

    if (pdwHelpContext == NULL)
        return E_INVALIDARG;

    *pdwHelpContext = This->help_context;

    return S_OK;
}

static const IErrorInfoVtbl ErrorInfoVtbl =
{
    IErrorInfoImpl_QueryInterface,
    IErrorInfoImpl_AddRef,
    IErrorInfoImpl_Release,
    IErrorInfoImpl_GetGUID,
    IErrorInfoImpl_GetSource,
    IErrorInfoImpl_GetDescription,
    IErrorInfoImpl_GetHelpFile,
    IErrorInfoImpl_GetHelpContext
};

static HRESULT WINAPI errorrec_QueryInterface(IErrorRecords *iface, REFIID riid, void **ppvObject)
{
    ErrorInfoImpl *This = impl_from_IErrorRecords(iface);
    return IErrorInfo_QueryInterface(&This->IErrorInfo_iface, riid, ppvObject);
}

static ULONG WINAPI WINAPI errorrec_AddRef(IErrorRecords *iface)
{
    ErrorInfoImpl *This = impl_from_IErrorRecords(iface);
    return IErrorInfo_AddRef(&This->IErrorInfo_iface);
}

static ULONG WINAPI WINAPI errorrec_Release(IErrorRecords *iface)
{
    ErrorInfoImpl *This = impl_from_IErrorRecords(iface);
    return IErrorInfo_Release(&This->IErrorInfo_iface);
}

static HRESULT WINAPI errorrec_AddErrorRecord(IErrorRecords *iface, ERRORINFO *pErrorInfo,
        DWORD dwLookupID, DISPPARAMS *pdispparams, IUnknown *punkCustomError, DWORD dwDynamicErrorID)
{
    ErrorInfoImpl *This = impl_from_IErrorRecords(iface);
    struct ErrorEntry *entry;

    TRACE("(%p)->(%p %d %p %p %d)\n", This, pErrorInfo, dwLookupID, pdispparams, punkCustomError, dwDynamicErrorID);

    if(!pErrorInfo)
        return E_INVALIDARG;

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

    entry->info = *pErrorInfo;
    if(pdispparams)
        entry->dispparams = *pdispparams;
    entry->unknown = punkCustomError;
    if(entry->unknown)
        IUnknown_AddRef(entry->unknown);
    entry->lookupID = dwDynamicErrorID;

    list_add_head(&This->errors, &entry->entry);

    return S_OK;
}

static HRESULT WINAPI errorrec_GetBasicErrorInfo(IErrorRecords *iface, ULONG ulRecordNum,
        ERRORINFO *pErrorInfo)
{
    ErrorInfoImpl *This = impl_from_IErrorRecords(iface);

    FIXME("(%p)->(%d %p)\n", This, ulRecordNum, pErrorInfo);

    if(!pErrorInfo)
        return E_INVALIDARG;

    if(ulRecordNum > list_count(&This->errors))
        return DB_E_BADRECORDNUM;

    return E_NOTIMPL;
}

static HRESULT WINAPI errorrec_GetCustomErrorObject(IErrorRecords *iface, ULONG ulRecordNum,
        REFIID riid, IUnknown **ppObject)
{
    ErrorInfoImpl *This = impl_from_IErrorRecords(iface);

    FIXME("(%p)->(%d %s, %p)\n", This, ulRecordNum, debugstr_guid(riid), ppObject);

    if (!ppObject)
        return E_INVALIDARG;

    *ppObject = NULL;

    if(ulRecordNum > list_count(&This->errors))
        return DB_E_BADRECORDNUM;

    return E_NOTIMPL;
}

static HRESULT WINAPI errorrec_GetErrorInfo(IErrorRecords *iface, ULONG ulRecordNum,
        LCID lcid, IErrorInfo **ppErrorInfo)
{
    ErrorInfoImpl *This = impl_from_IErrorRecords(iface);

    FIXME("(%p)->(%d %d, %p)\n", This, ulRecordNum, lcid, ppErrorInfo);

    if (!ppErrorInfo)
        return E_INVALIDARG;

    if(ulRecordNum > list_count(&This->errors))
        return DB_E_BADRECORDNUM;

    return E_NOTIMPL;
}

static HRESULT WINAPI errorrec_GetErrorParameters(IErrorRecords *iface, ULONG ulRecordNum,
        DISPPARAMS *pdispparams)
{
    ErrorInfoImpl *This = impl_from_IErrorRecords(iface);

    FIXME("(%p)->(%d %p)\n", This, ulRecordNum, pdispparams);

    if (!pdispparams)
        return E_INVALIDARG;

    if(ulRecordNum > list_count(&This->errors))
        return DB_E_BADRECORDNUM;

    return E_NOTIMPL;
}

static HRESULT WINAPI errorrec_GetRecordCount(IErrorRecords *iface, ULONG *records)
{
    ErrorInfoImpl *This = impl_from_IErrorRecords(iface);

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

    if(!records)
        return E_INVALIDARG;

    *records = list_count(&This->errors);

    TRACE("<--(%d)\n", *records);

    return S_OK;
}

static const IErrorRecordsVtbl ErrorRecordsVtbl =
{
    errorrec_QueryInterface,
    errorrec_AddRef,
    errorrec_Release,
    errorrec_AddErrorRecord,
    errorrec_GetBasicErrorInfo,
    errorrec_GetCustomErrorObject,
    errorrec_GetErrorInfo,
    errorrec_GetErrorParameters,
    errorrec_GetRecordCount
};

HRESULT create_error_info(IUnknown *outer, void **obj)
{
    ErrorInfoImpl *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->IErrorInfo_iface.lpVtbl = &ErrorInfoVtbl;
    This->IErrorRecords_iface.lpVtbl = &ErrorRecordsVtbl;
    This->ref = 1;
    This->source = NULL;
    This->description = NULL;
    This->help_file = NULL;
    This->help_context = 0;

    list_init(&This->errors);

    *obj = &This->IErrorInfo_iface;

    return S_OK;
}
