/*
 * Implementation of the Microsoft Installer (msi.dll)
 *
 * Copyright 2002-2004 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "msi.h"
#include "msiquery.h"
#include "objbase.h"
#include "objidl.h"
#include "msipriv.h"
#include "winnls.h"

#include "query.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);

#if 0
typedef struct tagMSIQUERY
{
    MSIOBJECTHDR hdr;
    MSIVIEW *view;
    UINT row;
    MSIDATABASE *db;
} MSIQUERY;
#endif

UINT WINAPI MsiDatabaseIsTablePersistentA(
              MSIHANDLE hDatabase, LPSTR szTableName)
{
    FIXME("%lx %s\n", hDatabase, debugstr_a(szTableName));
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiDatabaseIsTablePersistentW(
              MSIHANDLE hDatabase, LPWSTR szTableName)
{
    FIXME("%lx %s\n", hDatabase, debugstr_w(szTableName));
    return ERROR_CALL_NOT_IMPLEMENTED;
}

void MSI_CloseView( MSIOBJECTHDR *arg )
{
    MSIQUERY *query = (MSIQUERY*) arg;

    if( query->view && query->view->ops->delete )
        query->view->ops->delete( query->view );
    msiobj_release( &query->db->hdr );
}

UINT VIEW_find_column( MSIVIEW *table, LPWSTR name, UINT *n )
{
    LPWSTR col_name;
    UINT i, count, r;

    r = table->ops->get_dimensions( table, NULL, &count );
    if( r != ERROR_SUCCESS )
        return r;

    for( i=1; i<=count; i++ )
    {
        INT x;

        col_name = NULL;
        r = table->ops->get_column_info( table, i, &col_name, NULL );
        if( r != ERROR_SUCCESS )
            return r;
        x = lstrcmpW( name, col_name );
        HeapFree( GetProcessHeap(), 0, col_name );
        if( !x )
        {
            *n = i;
            return ERROR_SUCCESS;
        }
    }

    return ERROR_INVALID_PARAMETER;
}

UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb,
              LPCSTR szQuery, MSIHANDLE *phView)
{
    UINT r;
    LPWSTR szwQuery;

    TRACE("%ld %s %p\n", hdb, debugstr_a(szQuery), phView);

    if( szQuery )
    {
        UINT len = MultiByteToWideChar( CP_ACP, 0, szQuery, -1, NULL, 0 );
        szwQuery = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
        if( !szwQuery )
            return ERROR_FUNCTION_FAILED;
        MultiByteToWideChar( CP_ACP, 0, szQuery, -1, szwQuery, len );
    }
    else
        szwQuery = NULL;

    r = MsiDatabaseOpenViewW( hdb, szwQuery, phView);

    return r;
}

UINT MSI_DatabaseOpenViewW(MSIDATABASE *db,
              LPCWSTR szQuery, MSIQUERY **pView)
{
    MSIQUERY *query;
    UINT r;

    TRACE("%s %p\n", debugstr_w(szQuery), pView);

    if( !szQuery)
        return ERROR_INVALID_PARAMETER;

    /* pre allocate a handle to hold a pointer to the view */
    query = alloc_msiobject( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY),
                              MSI_CloseView );
    if( !query )
        return ERROR_FUNCTION_FAILED;

    msiobj_addref( &db->hdr );
    query->row = 0;
    query->db = db;
    query->view = NULL;

    r = MSI_ParseSQL( db, szQuery, &query->view );
    if( r == ERROR_SUCCESS )
    {
        msiobj_addref( &query->hdr );
        *pView = query;
    }

    msiobj_release( &query->hdr );
    return r;
}

UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
              LPCWSTR szQuery, MSIHANDLE *phView)
{
    MSIDATABASE *db;
    MSIQUERY *query = NULL;
    UINT ret;

    TRACE("%s %p\n", debugstr_w(szQuery), phView);

    db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
    if( !db )
        return ERROR_INVALID_HANDLE;

    ret = MSI_DatabaseOpenViewW( db, szQuery, &query );
    if( ret == ERROR_SUCCESS )
    {
        *phView = alloc_msihandle( &query->hdr );
        msiobj_release( &query->hdr );
    }
    msiobj_release( &db->hdr );

    return ret;
}

UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
{
    MSIVIEW *view;
    MSIRECORD *rec;
    UINT row_count = 0, col_count = 0, i, ival, ret, type;

    TRACE("%p %p\n", query, prec );

    view = query->view;
    if( !view )
        return ERROR_FUNCTION_FAILED;

    ret = view->ops->get_dimensions( view, &row_count, &col_count );
    if( ret )
        return ret;
    if( !col_count )
        return ERROR_INVALID_PARAMETER;

    if( query->row >= row_count )
        return ERROR_NO_MORE_ITEMS;

    rec = MSI_CreateRecord( col_count );
    if( !rec )
        return ERROR_FUNCTION_FAILED;

    for( i=1; i<=col_count; i++ )
    {
        ret = view->ops->get_column_info( view, i, NULL, &type );
        if( ret )
        {
            ERR("Error getting column type for %d\n", i );
            continue;
        }
        if (( type != MSITYPE_BINARY) && (type != (MSITYPE_BINARY |
                                                   MSITYPE_NULLABLE)))
        {
            ret = view->ops->fetch_int( view, query->row, i, &ival );
            if( ret )
            {
                ERR("Error fetching data for %d\n", i );
                continue;
            }
            if( ! (type & MSITYPE_VALID ) )
                ERR("Invalid type!\n");

            /* check if it's nul (0) - if so, don't set anything */
            if( !ival )
                continue;

            if( type & MSITYPE_STRING )
            {
                LPWSTR sval;

                sval = MSI_makestring( query->db, ival );
                MSI_RecordSetStringW( rec, i, sval );
                HeapFree( GetProcessHeap(), 0, sval );
            }
            else
            {
                if( (type & MSI_DATASIZEMASK) == 2 )
                    MSI_RecordSetInteger( rec, i, ival - (1<<15) );
                else
                    MSI_RecordSetInteger( rec, i, ival - (1<<31) );
            }
        }
        else
        {
            IStream *stm = NULL;

            ret = view->ops->fetch_stream( view, query->row, i, &stm );
            if( ( ret == ERROR_SUCCESS ) && stm )
            {
                MSI_RecordSetIStream( rec, i, stm );
                IStream_Release( stm );
            }
            else
                ERR("failed to get stream\n");
        }
    }
    query->row ++;

    *prec = rec;

    return ERROR_SUCCESS;
}

UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
{
    MSIQUERY *query;
    MSIRECORD *rec = NULL;
    UINT ret;

    TRACE("%ld %p\n", hView, record);

    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
    if( !query )
        return ERROR_INVALID_HANDLE;
    ret = MSI_ViewFetch( query, &rec );
    if( ret == ERROR_SUCCESS )
    {
        *record = alloc_msihandle( &rec->hdr );
        msiobj_release( &rec->hdr );
    }
    msiobj_release( &query->hdr );
    return ret;
}

UINT MSI_ViewClose(MSIQUERY *query)
{
    MSIVIEW *view;

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

    view = query->view;
    if( !view )
        return ERROR_FUNCTION_FAILED;
    if( !view->ops->close )
        return ERROR_FUNCTION_FAILED;

    return view->ops->close( view );
}

UINT WINAPI MsiViewClose(MSIHANDLE hView)
{
    MSIQUERY *query;
    UINT ret;

    TRACE("%ld\n", hView );

    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
    if( !query )
        return ERROR_INVALID_HANDLE;

    ret = MSI_ViewClose( query );
    msiobj_release( &query->hdr );
    return ret;
}

UINT MSI_ViewExecute(MSIQUERY *query, MSIRECORD *rec )
{
    MSIVIEW *view;

    TRACE("%p %p\n", query, rec);

    view = query->view;
    if( !view )
        return ERROR_FUNCTION_FAILED;
    if( !view->ops->execute )
        return ERROR_FUNCTION_FAILED;
    query->row = 0;

    return view->ops->execute( view, rec );
}

UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
{
    MSIQUERY *query;
    MSIRECORD *rec = NULL;
    UINT ret;
    
    TRACE("%ld %ld\n", hView, hRec);

    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
    if( !query )
        return ERROR_INVALID_HANDLE;

    if( hRec )
    {
        rec = msihandle2msiinfo( hRec, MSIHANDLETYPE_RECORD );
        if( !rec )
        {
            ret = ERROR_INVALID_HANDLE;
            goto out;
        }
    }

    ret = MSI_ViewExecute( query, rec );
out:
    if( query )
        msiobj_release( &query->hdr );
    if( rec )
        msiobj_release( &rec->hdr );

    return ret;
}

UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
{
    MSIVIEW *view;
    MSIQUERY *query;
    MSIHANDLE handle;
    UINT ret, i, count = 0, type;
    LPWSTR name;

    TRACE("%ld %d %p\n", hView, info, hRec);

    query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
    if( !query )
        return ERROR_INVALID_HANDLE;

    view = query->view;
    if( !view )
        return ERROR_FUNCTION_FAILED;

    if( !view->ops->get_dimensions )
        return ERROR_FUNCTION_FAILED;

    ret = view->ops->get_dimensions( view, NULL, &count );
    if( ret )
        return ret;
    if( !count )
        return ERROR_INVALID_PARAMETER;

    handle = MsiCreateRecord( count );
    if( !handle )
        return ERROR_FUNCTION_FAILED;

    for( i=0; i<count; i++ )
    {
        name = NULL;
        ret = view->ops->get_column_info( view, i+1, &name, &type );
        if( ret != ERROR_SUCCESS )
            continue;
        MsiRecordSetStringW( handle, i+1, name );
        HeapFree( GetProcessHeap(), 0, name );
    }

    *hRec = handle;

    return ERROR_SUCCESS;
}

UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb, 
                 LPCSTR szTransformFile, int iErrorCond)
{
    FIXME("%ld %s %d\n", hdb, debugstr_a(szTransformFile), iErrorCond);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb, 
                 LPCWSTR szTransformFile, int iErrorCond)
{
    FIXME("%ld %s %d\n", hdb, debugstr_w(szTransformFile), iErrorCond);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiDatabaseGenerateTransformA( MSIHANDLE hdb, MSIHANDLE hdbref,
                 LPCSTR szTransformFile, int iReserved1, int iReserved2 )
{
    FIXME("%ld %ld %s %d %d\n", hdb, hdbref, 
           debugstr_a(szTransformFile), iReserved1, iReserved2);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiDatabaseGenerateTransformW( MSIHANDLE hdb, MSIHANDLE hdbref,
                 LPCWSTR szTransformFile, int iReserved1, int iReserved2 )
{
    FIXME("%ld %ld %s %d %d\n", hdb, hdbref, 
           debugstr_w(szTransformFile), iReserved1, iReserved2);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
{
    MSIDATABASE *db;
    UINT r;

    TRACE("%ld\n", hdb);

    db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
    if( !db )
        return ERROR_INVALID_HANDLE;

    /* FIXME: lock the database */

    r = MSI_CommitTables( db );

    /* FIXME: unlock the database */

    return r;
}

UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb, 
                    LPCSTR table, MSIHANDLE* rec)
{
    FIXME("%ld %s %p\n", hdb, debugstr_a(table), rec);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb,
                    LPCWSTR table, MSIHANDLE* rec)
{
    FIXME("%ld %s %p\n", hdb, debugstr_w(table), rec);
    return ERROR_CALL_NOT_IMPLEMENTED;
}

UINT WINAPI MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE
hRecord)
{
    FIXME("%ld %x %ld\n",hView, eModifyMode, hRecord);
    return ERROR_CALL_NOT_IMPLEMENTED;
}
