/*
 * Implementation of the Microsoft Installer (msi.dll)
 *
 * Copyright 2002 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.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(msidb);

#define MSI_HASH_TABLE_SIZE 37

typedef struct tagMSIHASHENTRY
{
    struct tagMSIHASHENTRY *next;
    UINT value;
    UINT row;
} MSIHASHENTRY;

/* below is the query interface to a table */

typedef struct tagMSIWHEREVIEW
{
    MSIVIEW        view;
    MSIDATABASE   *db;
    MSIVIEW       *table;
    UINT           row_count;
    MSIHASHENTRY **reorder;
    struct expr   *cond;
    UINT           rec_index;
} MSIWHEREVIEW;

static void free_hash_table(MSIHASHENTRY **table)
{
    MSIHASHENTRY *new, *old;
    int i;

    if (!table)
        return;

    for (i = 0; i < MSI_HASH_TABLE_SIZE; i++)
    {
        new = table[i];

        while (new)
        {
            old = new;
            new = old->next;
            msi_free(old);
        }

        table[i] = NULL;
    }

    msi_free(table);
}

static UINT find_entry_in_hash(MSIHASHENTRY **table, UINT row, UINT *val)
{
    MSIHASHENTRY *entry;

    if (!table)
        return ERROR_SUCCESS;

    if (!(entry = table[row % MSI_HASH_TABLE_SIZE]))
    {
        WARN("Row not found in hash table!\n");
        return ERROR_FUNCTION_FAILED;
    }

    while (entry && entry->row != row)
        entry = entry->next;

    if (entry) *val = entry->value;
    return ERROR_SUCCESS;
}

static UINT add_entry_to_hash(MSIHASHENTRY **table, UINT row, UINT val)
{
    MSIHASHENTRY *new = msi_alloc(sizeof(MSIHASHENTRY));
    MSIHASHENTRY *prev;

    if (!new)
        return ERROR_OUTOFMEMORY;

    new->next = NULL;
    new->value = val;
    new->row = row;

    prev = table[row % MSI_HASH_TABLE_SIZE];
    if (prev)
        new->next = prev;

    table[row % MSI_HASH_TABLE_SIZE] = new;

    return ERROR_SUCCESS;
}

static UINT WHERE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
    UINT r;

    TRACE("%p %d %d %p\n", wv, row, col, val );

    if( !wv->table )
        return ERROR_FUNCTION_FAILED;

    if( row > wv->row_count )
        return ERROR_NO_MORE_ITEMS;

    r = find_entry_in_hash(wv->reorder, row, &row);
    if (r != ERROR_SUCCESS)
        return r;

    return wv->table->ops->fetch_int( wv->table, row, col, val );
}

static UINT WHERE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
    UINT r;

    TRACE("%p %d %d %p\n", wv, row, col, stm );

    if( !wv->table )
        return ERROR_FUNCTION_FAILED;

    if( row > wv->row_count )
        return ERROR_NO_MORE_ITEMS;

    r = find_entry_in_hash(wv->reorder, row, &row);
    if (r != ERROR_SUCCESS)
        return r;

    return wv->table->ops->fetch_stream( wv->table, row, col, stm );
}

static UINT WHERE_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW *)view;
    UINT r;

    TRACE("%p %d %p\n", wv, row, rec );

    if (!wv->table)
        return ERROR_FUNCTION_FAILED;

    if (row > wv->row_count)
        return ERROR_NO_MORE_ITEMS;

    r = find_entry_in_hash(wv->reorder, row, &row);
    if (r != ERROR_SUCCESS)
        return r;

    return wv->table->ops->get_row(wv->table, row, rec);
}

static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
    UINT r;

    TRACE("%p %d %p %08x\n", wv, row, rec, mask );

    if( !wv->table )
         return ERROR_FUNCTION_FAILED;

    if( row > wv->row_count )
        return ERROR_NO_MORE_ITEMS;

    r = find_entry_in_hash(wv->reorder, row, &row);
    if (r != ERROR_SUCCESS)
        return r;

    return wv->table->ops->set_row( wv->table, row, rec, mask );
}

static UINT WHERE_delete_row(struct tagMSIVIEW *view, UINT row)
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW *)view;
    UINT r;

    TRACE("(%p %d)\n", view, row);

    if ( !wv->table )
        return ERROR_FUNCTION_FAILED;

    if ( row > wv->row_count )
        return ERROR_NO_MORE_ITEMS;

    r = find_entry_in_hash( wv->reorder, row, &row );
    if ( r != ERROR_SUCCESS )
        return r;

    return wv->table->ops->delete_row( wv->table, row );
}

static INT INT_evaluate_binary( INT lval, UINT op, INT rval )
{
    switch( op )
    {
    case OP_EQ:
        return ( lval == rval );
    case OP_AND:
        return ( lval && rval );
    case OP_OR:
        return ( lval || rval );
    case OP_GT:
        return ( lval > rval );
    case OP_LT:
        return ( lval < rval );
    case OP_LE:
        return ( lval <= rval );
    case OP_GE:
        return ( lval >= rval );
    case OP_NE:
        return ( lval != rval );
    default:
        ERR("Unknown operator %d\n", op );
    }
    return 0;
}

static INT INT_evaluate_unary( INT lval, UINT op )
{
    switch( op )
    {
    case OP_ISNULL:
        return ( !lval );
    case OP_NOTNULL:
        return ( lval );
    default:
        ERR("Unknown operator %d\n", op );
    }
    return 0;
}

static const WCHAR *STRING_evaluate( MSIWHEREVIEW *wv, UINT row,
                                     const struct expr *expr,
                                     const MSIRECORD *record )
{
    UINT val = 0, r;

    switch( expr->type )
    {
    case EXPR_COL_NUMBER_STRING:
        r = wv->table->ops->fetch_int( wv->table, row, expr->u.col_number, &val );
        if( r != ERROR_SUCCESS )
            return NULL;
        return msi_string_lookup_id( wv->db->strings, val );

    case EXPR_SVAL:
        return expr->u.sval;

    case EXPR_WILDCARD:
        return MSI_RecordGetString( record, ++wv->rec_index );

    default:
        ERR("Invalid expression type\n");
        break;
    }
    return NULL;
}

static UINT STRCMP_Evaluate( MSIWHEREVIEW *wv, UINT row, const struct expr *cond,
                             INT *val, const MSIRECORD *record )
{
    int sr;
    const WCHAR *l_str, *r_str;

    l_str = STRING_evaluate( wv, row, cond->u.expr.left, record );
    r_str = STRING_evaluate( wv, row, cond->u.expr.right, record );
    if( l_str == r_str ||
        ((!l_str || !*l_str) && (!r_str || !*r_str)) )
        sr = 0;
    else if( l_str && ! r_str )
        sr = 1;
    else if( r_str && ! l_str )
        sr = -1;
    else
        sr = lstrcmpW( l_str, r_str );

    *val = ( cond->u.expr.op == OP_EQ && ( sr == 0 ) ) ||
           ( cond->u.expr.op == OP_NE && ( sr != 0 ) );

    return ERROR_SUCCESS;
}

static UINT WHERE_evaluate( MSIWHEREVIEW *wv, UINT row,
                            struct expr *cond, INT *val, MSIRECORD *record )
{
    UINT r, tval;
    INT lval, rval;

    if( !cond )
        return ERROR_SUCCESS;

    switch( cond->type )
    {
    case EXPR_COL_NUMBER:
        r = wv->table->ops->fetch_int( wv->table, row, cond->u.col_number, &tval );
        *val = tval - 0x8000;
        return ERROR_SUCCESS;

    case EXPR_COL_NUMBER32:
        r = wv->table->ops->fetch_int( wv->table, row, cond->u.col_number, &tval );
        *val = tval - 0x80000000;
        return r;

    case EXPR_UVAL:
        *val = cond->u.uval;
        return ERROR_SUCCESS;

    case EXPR_COMPLEX:
        r = WHERE_evaluate( wv, row, cond->u.expr.left, &lval, record );
        if( r != ERROR_SUCCESS )
            return r;
        r = WHERE_evaluate( wv, row, cond->u.expr.right, &rval, record );
        if( r != ERROR_SUCCESS )
            return r;
        *val = INT_evaluate_binary( lval, cond->u.expr.op, rval );
        return ERROR_SUCCESS;

    case EXPR_UNARY:
        r = wv->table->ops->fetch_int( wv->table, row, cond->u.expr.left->u.col_number, &tval );
        if( r != ERROR_SUCCESS )
            return r;
        *val = INT_evaluate_unary( tval, cond->u.expr.op );
        return ERROR_SUCCESS;

    case EXPR_STRCMP:
        return STRCMP_Evaluate( wv, row, cond, val, record );

    case EXPR_WILDCARD:
        *val = MSI_RecordGetInteger( record, ++wv->rec_index );
        return ERROR_SUCCESS;

    default:
        ERR("Invalid expression type\n");
        break;
    }

    return ERROR_SUCCESS;
}

static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
    UINT count = 0, r, i;
    INT val;
    MSIVIEW *table = wv->table;

    TRACE("%p %p\n", wv, record);

    if( !table )
         return ERROR_FUNCTION_FAILED;

    r = table->ops->execute( table, record );
    if( r != ERROR_SUCCESS )
        return r;

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

    free_hash_table(wv->reorder);
    wv->reorder = msi_alloc_zero(MSI_HASH_TABLE_SIZE * sizeof(MSIHASHENTRY *));
    if( !wv->reorder )
        return ERROR_OUTOFMEMORY;

    wv->row_count = 0;
    if (wv->cond->type == EXPR_STRCMP)
    {
        MSIITERHANDLE handle = NULL;
        UINT row, value, col;
        struct expr *col_cond = wv->cond->u.expr.left;
        struct expr *val_cond = wv->cond->u.expr.right;

        /* swap conditionals */
        if (col_cond->type != EXPR_COL_NUMBER_STRING)
        {
            val_cond = wv->cond->u.expr.left;
            col_cond = wv->cond->u.expr.right;
        }

        if ((col_cond->type == EXPR_COL_NUMBER_STRING) && (val_cond->type == EXPR_SVAL))
        {
            col = col_cond->u.col_number;
            /* special case for "" - translate it into nil */
            if (!val_cond->u.sval[0])
                value = 0;
            else
            {
                r = msi_string2idW(wv->db->strings, val_cond->u.sval, &value);
                if (r != ERROR_SUCCESS)
                {
                    TRACE("no id for %s, assuming it doesn't exist in the table\n", debugstr_w(wv->cond->u.expr.right->u.sval));
                    return ERROR_SUCCESS;
                }
            }

            do
            {
                r = table->ops->find_matching_rows(table, col, value, &row, &handle);
                if (r == ERROR_SUCCESS)
                    add_entry_to_hash(wv->reorder, wv->row_count++, row);
            } while (r == ERROR_SUCCESS);

            if (r == ERROR_NO_MORE_ITEMS)
                return ERROR_SUCCESS;
            else
                return r;
        }
        /* else fallback to slow case */
    }

    for( i=0; i<count; i++ )
    {
        val = 0;
        wv->rec_index = 0;
        r = WHERE_evaluate( wv, i, wv->cond, &val, record );
        if( r != ERROR_SUCCESS )
            return r;
        if( val )
            add_entry_to_hash( wv->reorder, wv->row_count++, i );
    }

    return ERROR_SUCCESS;
}

static UINT WHERE_close( struct tagMSIVIEW *view )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;

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

    if( !wv->table )
        return ERROR_FUNCTION_FAILED;

    return wv->table->ops->close( wv->table );
}

static UINT WHERE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;

    TRACE("%p %p %p\n", wv, rows, cols );

    if( !wv->table )
         return ERROR_FUNCTION_FAILED;

    if( rows )
    {
        if( !wv->reorder )
            return ERROR_FUNCTION_FAILED;
        *rows = wv->row_count;
    }

    return wv->table->ops->get_dimensions( wv->table, NULL, cols );
}

static UINT WHERE_get_column_info( struct tagMSIVIEW *view,
                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
                LPWSTR *table_name)
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;

    TRACE("%p %d %p %p %p %p\n", wv, n, name, type, temporary, table_name );

    if( !wv->table )
         return ERROR_FUNCTION_FAILED;

    return wv->table->ops->get_column_info( wv->table, n, name,
                                            type, temporary, table_name );
}

static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
                          MSIRECORD *rec, UINT row )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;

    TRACE("%p %d %p\n", wv, eModifyMode, rec);

    find_entry_in_hash(wv->reorder, row - 1, &row);
    row++;

    return wv->table->ops->modify( wv->table, eModifyMode, rec, row );
}

static UINT WHERE_delete( struct tagMSIVIEW *view )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;

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

    if( wv->table )
        wv->table->ops->delete( wv->table );
    wv->table = 0;

    free_hash_table(wv->reorder);
    wv->reorder = NULL;
    wv->row_count = 0;

    msiobj_release( &wv->db->hdr );
    msi_free( wv );

    return ERROR_SUCCESS;
}

static UINT WHERE_find_matching_rows( struct tagMSIVIEW *view, UINT col,
    UINT val, UINT *row, MSIITERHANDLE *handle )
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
    UINT r;

    TRACE("%p, %d, %u, %p\n", view, col, val, *handle);

    if( !wv->table )
         return ERROR_FUNCTION_FAILED;

    r = wv->table->ops->find_matching_rows( wv->table, col, val, row, handle );
    if (r != ERROR_SUCCESS)
        return r;

    if( *row > wv->row_count )
        return ERROR_NO_MORE_ITEMS;

    return find_entry_in_hash(wv->reorder, *row, row);
}

static UINT WHERE_sort(struct tagMSIVIEW *view, column_info *columns)
{
    MSIWHEREVIEW *wv = (MSIWHEREVIEW *)view;

    TRACE("%p %p\n", view, columns);

    return wv->table->ops->sort(wv->table, columns);
}

static const MSIVIEWOPS where_ops =
{
    WHERE_fetch_int,
    WHERE_fetch_stream,
    WHERE_get_row,
    WHERE_set_row,
    NULL,
    WHERE_delete_row,
    WHERE_execute,
    WHERE_close,
    WHERE_get_dimensions,
    WHERE_get_column_info,
    WHERE_modify,
    WHERE_delete,
    WHERE_find_matching_rows,
    NULL,
    NULL,
    NULL,
    NULL,
    WHERE_sort,
    NULL,
};

static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr *cond,
                                   UINT *valid )
{
    UINT r, val = 0;

    switch( cond->type )
    {
    case EXPR_COLUMN:
        r = VIEW_find_column( table, cond->u.column.column,
                              cond->u.column.table, &val );
        if( r == ERROR_SUCCESS )
        {
            UINT type = 0;
            r = table->ops->get_column_info( table, val, NULL, &type,
                                             NULL, NULL );
            if( r == ERROR_SUCCESS )
            {
                if (type&MSITYPE_STRING)
                    cond->type = EXPR_COL_NUMBER_STRING;
                else if ((type&0xff) == 4)
                    cond->type = EXPR_COL_NUMBER32;
                else
                    cond->type = EXPR_COL_NUMBER;
                cond->u.col_number = val;
                *valid = 1;
            }
            else
                *valid = 0;
        }
        else
        {
            *valid = 0;
            WARN("Couldn't find column %s.%s\n", debugstr_w( cond->u.column.table ), debugstr_w( cond->u.column.column ) );
        }
        break;
    case EXPR_COMPLEX:
        r = WHERE_VerifyCondition( db, table, cond->u.expr.left, valid );
        if( r != ERROR_SUCCESS )
            return r;
        if( !*valid )
            return ERROR_SUCCESS;
        r = WHERE_VerifyCondition( db, table, cond->u.expr.right, valid );
        if( r != ERROR_SUCCESS )
            return r;

        /* check the type of the comparison */
        if( ( cond->u.expr.left->type == EXPR_SVAL ) ||
            ( cond->u.expr.left->type == EXPR_COL_NUMBER_STRING ) ||
            ( cond->u.expr.right->type == EXPR_SVAL ) ||
            ( cond->u.expr.right->type == EXPR_COL_NUMBER_STRING ) )
        {
            switch( cond->u.expr.op )
            {
            case OP_EQ:
            case OP_NE:
                break;
            default:
                *valid = FALSE;
                return ERROR_INVALID_PARAMETER;
            }

            /* FIXME: check we're comparing a string to a column */

            cond->type = EXPR_STRCMP;
        }

        break;
    case EXPR_UNARY:
        if ( cond->u.expr.left->type != EXPR_COLUMN )
        {
            *valid = FALSE;
            return ERROR_INVALID_PARAMETER;
        }
        r = WHERE_VerifyCondition( db, table, cond->u.expr.left, valid );
        if( r != ERROR_SUCCESS )
            return r;
        break;
    case EXPR_IVAL:
        *valid = 1;
        cond->type = EXPR_UVAL;
        cond->u.uval = cond->u.ival;
        break;
    case EXPR_WILDCARD:
        *valid = 1;
        break;
    case EXPR_SVAL:
        *valid = 1;
        break;
    default:
        ERR("Invalid expression type\n");
        *valid = 0;
        break;
    }

    return ERROR_SUCCESS;
}

UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
                       struct expr *cond )
{
    MSIWHEREVIEW *wv = NULL;
    UINT count = 0, r, valid = 0;

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

    r = table->ops->get_dimensions( table, NULL, &count );
    if( r != ERROR_SUCCESS )
    {
        ERR("can't get table dimensions\n");
        return r;
    }

    if( cond )
    {
        r = WHERE_VerifyCondition( db, table, cond, &valid );
        if( r != ERROR_SUCCESS )
            return r;
        if( !valid )
            return ERROR_FUNCTION_FAILED;
    }

    wv = msi_alloc_zero( sizeof *wv );
    if( !wv )
        return ERROR_FUNCTION_FAILED;
    
    /* fill the structure */
    wv->view.ops = &where_ops;
    msiobj_addref( &db->hdr );
    wv->db = db;
    wv->table = table;
    wv->row_count = 0;
    wv->reorder = NULL;
    wv->cond = cond;
    wv->rec_index = 0;
    *view = (MSIVIEW*) wv;

    return ERROR_SUCCESS;
}
