/*
 * Implementation of the Microsoft Installer (msi.dll)
 *
 * Copyright 2005 Aric Stewart 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 <stdio.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winreg.h"
#include "msi.h"
#include "msipriv.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(msi);

typedef UINT (*EVENTHANDLER)(MSIPACKAGE*,LPCWSTR,msi_dialog *);

struct control_events
{
    const WCHAR *event;
    EVENTHANDLER handler;
};

struct subscriber {
    struct list entry;
    msi_dialog *dialog;
    LPWSTR event;
    LPWSTR control;
    LPWSTR attribute;
};

static UINT ControlEvent_HandleControlEvent(MSIPACKAGE *, LPCWSTR, LPCWSTR, msi_dialog*);

/*
 * Create a dialog box and run it if it's modal
 */
static UINT event_do_dialog( MSIPACKAGE *package, LPCWSTR name, msi_dialog *parent, BOOL destroy_modeless )
{
    msi_dialog *dialog;
    UINT r;

    /* create a new dialog */
    dialog = msi_dialog_create( package, name, parent,
                                ControlEvent_HandleControlEvent );
    if( dialog )
    {
        /* kill the current modeless dialog */
        if( destroy_modeless && package->dialog )
        {
            msi_dialog_destroy( package->dialog );
            package->dialog = NULL;
        }

        /* modeless dialogs return an error message */
        r = msi_dialog_run_message_loop( dialog );
        if( r == ERROR_SUCCESS )
            msi_dialog_destroy( dialog );
        else
            package->dialog = dialog;
    }
    else
        r = ERROR_FUNCTION_FAILED;

    return r;
}


/*
 * End a modal dialog box
 */
static UINT ControlEvent_EndDialog(MSIPACKAGE* package, LPCWSTR argument, 
                                   msi_dialog* dialog)
{
    static const WCHAR szExit[] = {'E','x','i','t',0};
    static const WCHAR szRetry[] = {'R','e','t','r','y',0};
    static const WCHAR szIgnore[] = {'I','g','n','o','r','e',0};
    static const WCHAR szReturn[] = {'R','e','t','u','r','n',0};

    if (!strcmpW( argument, szExit ))
        package->CurrentInstallState = ERROR_INSTALL_USEREXIT;
    else if (!strcmpW( argument, szRetry ))
        package->CurrentInstallState = ERROR_INSTALL_SUSPEND;
    else if (!strcmpW( argument, szIgnore ))
        package->CurrentInstallState = ERROR_SUCCESS;
    else if (!strcmpW( argument, szReturn ))
    {
        msi_dialog *parent = msi_dialog_get_parent(dialog);
        msi_free(package->next_dialog);
        package->next_dialog = (parent) ? strdupW(msi_dialog_get_name(parent)) : NULL;
        package->CurrentInstallState = ERROR_SUCCESS;
    }
    else
    {
        ERR("Unknown argument string %s\n",debugstr_w(argument));
        package->CurrentInstallState = ERROR_FUNCTION_FAILED;
    }

    ControlEvent_CleanupDialogSubscriptions(package, msi_dialog_get_name( dialog ));
    msi_dialog_end_dialog( dialog );
    return ERROR_SUCCESS;
}

/*
 * transition from one modal dialog to another modal dialog
 */
static UINT ControlEvent_NewDialog(MSIPACKAGE* package, LPCWSTR argument, 
                                   msi_dialog *dialog)
{
    /* store the name of the next dialog, and signal this one to end */
    package->next_dialog = strdupW(argument);
    ControlEvent_CleanupSubscriptions(package);
    msi_dialog_end_dialog( dialog );
    return ERROR_SUCCESS;
}

/*
 * Create a new child dialog of an existing modal dialog
 */
static UINT ControlEvent_SpawnDialog(MSIPACKAGE* package, LPCWSTR argument, 
                              msi_dialog *dialog)
{
    /* don't destroy a modeless dialogs that might be our parent */
    event_do_dialog( package, argument, dialog, FALSE );
    if( package->CurrentInstallState != ERROR_SUCCESS )
        msi_dialog_end_dialog( dialog );
    return ERROR_SUCCESS;
}

/*
 * Creates a dialog that remains up for a period of time
 * based on a condition
 */
static UINT ControlEvent_SpawnWaitDialog(MSIPACKAGE* package, LPCWSTR argument, 
                                  msi_dialog* dialog)
{
    FIXME("Doing Nothing\n");
    return ERROR_SUCCESS;
}

static UINT ControlEvent_DoAction(MSIPACKAGE* package, LPCWSTR argument, 
                                  msi_dialog* dialog)
{
    ACTION_PerformAction(package, argument, -1);
    return ERROR_SUCCESS;
}

static UINT ControlEvent_AddLocal( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog )
{
    MSIFEATURE *feature;

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
        {
            if (feature->ActionRequest != INSTALLSTATE_LOCAL)
                msi_set_property( package->db, szPreselected, szOne );
            MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_LOCAL );
        }
    }
    return ERROR_SUCCESS;
}

static UINT ControlEvent_Remove( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog )
{
    MSIFEATURE *feature;

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
        {
            if (feature->ActionRequest != INSTALLSTATE_ABSENT)
                msi_set_property( package->db, szPreselected, szOne );
            MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_ABSENT );
        }
    }
    return ERROR_SUCCESS;
}

static UINT ControlEvent_AddSource( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog )
{
    MSIFEATURE *feature;

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
        {
            if (feature->ActionRequest != INSTALLSTATE_SOURCE)
                msi_set_property( package->db, szPreselected, szOne );
            MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_SOURCE );
        }
    }
    return ERROR_SUCCESS;
}

static UINT ControlEvent_SetTargetPath(MSIPACKAGE* package, LPCWSTR argument, 
                                   msi_dialog* dialog)
{
    static const WCHAR szSelectionPath[] = {'S','e','l','e','c','t','i','o','n','P','a','t','h',0};
    LPWSTR path = msi_dup_property( package->db, argument );
    MSIRECORD *rec = MSI_CreateRecord( 1 );
    UINT r = ERROR_SUCCESS;

    MSI_RecordSetStringW( rec, 1, path );
    ControlEvent_FireSubscribedEvent( package, szSelectionPath, rec );
    if (path)
    {
        /* failure to set the path halts the executing of control events */
        r = MSI_SetTargetPathW(package, argument, path);
        msi_free(path);
    }
    msi_free(&rec->hdr);
    return r;
}

static UINT ControlEvent_Reset(MSIPACKAGE* package, LPCWSTR argument, 
                                   msi_dialog* dialog)
{
    msi_dialog_reset(dialog);
    return ERROR_SUCCESS;
}

/*
 * Subscribed events
 */
static void free_subscriber( struct subscriber *sub )
{
    msi_free(sub->event);
    msi_free(sub->control);
    msi_free(sub->attribute);
    msi_free(sub);
}

VOID ControlEvent_SubscribeToEvent( MSIPACKAGE *package, msi_dialog *dialog,
                                    LPCWSTR event, LPCWSTR control, LPCWSTR attribute )
{
    struct subscriber *sub;

    TRACE("event %s control %s attribute %s\n", debugstr_w(event), debugstr_w(control), debugstr_w(attribute));

    LIST_FOR_EACH_ENTRY( sub, &package->subscriptions, struct subscriber, entry )
    {
        if (!strcmpiW( sub->event, event ) &&
            !strcmpiW( sub->control, control ) &&
            !strcmpiW( sub->attribute, attribute ))
        {
            TRACE("already subscribed\n");
            return;
        };
    }
    if (!(sub = msi_alloc( sizeof(*sub) ))) return;
    sub->dialog = dialog;
    sub->event = strdupW(event);
    sub->control = strdupW(control);
    sub->attribute = strdupW(attribute);
    list_add_tail( &package->subscriptions, &sub->entry );
}

VOID ControlEvent_FireSubscribedEvent( MSIPACKAGE *package, LPCWSTR event, MSIRECORD *rec )
{
    struct subscriber *sub;

    TRACE("Firing event %s\n", debugstr_w(event));

    LIST_FOR_EACH_ENTRY( sub, &package->subscriptions, struct subscriber, entry )
    {
        if (strcmpiW( sub->event, event )) continue;
        msi_dialog_handle_event( sub->dialog, sub->control, sub->attribute, rec );
    }
}

VOID ControlEvent_CleanupDialogSubscriptions(MSIPACKAGE *package, LPWSTR dialog)
{
    struct list *i, *t;
    struct subscriber *sub;

    LIST_FOR_EACH_SAFE( i, t, &package->subscriptions )
    {
        sub = LIST_ENTRY( i, struct subscriber, entry );

        if (strcmpW( msi_dialog_get_name( sub->dialog ), dialog ))
            continue;

        list_remove( &sub->entry );
        free_subscriber( sub );
    }
}

VOID ControlEvent_CleanupSubscriptions(MSIPACKAGE *package)
{
    struct list *i, *t;
    struct subscriber *sub;

    LIST_FOR_EACH_SAFE( i, t, &package->subscriptions )
    {
        sub = LIST_ENTRY( i, struct subscriber, entry );

        list_remove( &sub->entry );
        free_subscriber( sub );
    }
}

/*
 * ACTION_DialogBox()
 *
 * Return ERROR_SUCCESS if dialog is process and ERROR_FUNCTION_FAILED
 * if the given parameter is not a dialog box
 */
UINT ACTION_DialogBox( MSIPACKAGE* package, LPCWSTR szDialogName )
{
    UINT r = ERROR_SUCCESS;

    if( package->next_dialog )
        ERR("Already a next dialog... ignoring it\n");
    package->next_dialog = NULL;

    /*
     * Dialogs are chained by filling in the next_dialog member
     *  of the package structure, then terminating the current dialog.
     *  The code below sees the next_dialog member set, and runs the
     *  next dialog.
     * We fall out of the loop below if we come across a modeless
     *  dialog, as it returns ERROR_IO_PENDING when we try to run
     *  its message loop.
     */
    r = event_do_dialog( package, szDialogName, NULL, TRUE );
    while( r == ERROR_SUCCESS && package->next_dialog )
    {
        LPWSTR name = package->next_dialog;

        package->next_dialog = NULL;
        r = event_do_dialog( package, name, NULL, TRUE );
        msi_free( name );
    }

    if( r == ERROR_IO_PENDING )
        r = ERROR_SUCCESS;

    return r;
}

static UINT ControlEvent_SetInstallLevel(MSIPACKAGE* package, LPCWSTR argument,
                                          msi_dialog* dialog)
{
    int iInstallLevel = atolW(argument);

    TRACE("Setting install level: %i\n", iInstallLevel);

    return MSI_SetInstallLevel( package, iInstallLevel );
}

static UINT ControlEvent_DirectoryListUp(MSIPACKAGE *package, LPCWSTR argument,
                                         msi_dialog *dialog)
{
    return msi_dialog_directorylist_up( dialog );
}

static UINT ControlEvent_ReinstallMode(MSIPACKAGE *package, LPCWSTR argument,
                                       msi_dialog *dialog)
{
    return msi_set_property( package->db, szReinstallMode, argument );
}

static UINT ControlEvent_Reinstall( MSIPACKAGE *package, LPCWSTR argument,
                                    msi_dialog *dialog )
{
    return msi_set_property( package->db, szReinstall, argument );
}

static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument,
                                           msi_dialog *dialog)
{
    LPWSTR key, template;
    UINT ret = ERROR_SUCCESS;

    template = msi_dup_property( package->db, szPIDTemplate );
    key = msi_dup_property( package->db, szPIDKEY );

    if (key && template)
    {
        FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) );
        ret = msi_set_property( package->db, szProductID, key );
    }
    msi_free( template );
    msi_free( key );
    return ret;
}

static const WCHAR end_dialogW[] = {'E','n','d','D','i','a','l','o','g',0};
static const WCHAR new_dialogW[] = {'N','e','w','D','i','a','l','o','g',0};
static const WCHAR spawn_dialogW[] = {'S','p','a','w','n','D','i','a','l','o','g',0};
static const WCHAR spawn_wait_dialogW[] = {'S','p','a','w','n','W','a','i','t','D','i','a','l','o','g',0};
static const WCHAR do_actionW[] = {'D','o','A','c','t','i','o','n',0};
static const WCHAR add_localW[] = {'A','d','d','L','o','c','a','l',0};
static const WCHAR removeW[] = {'R','e','m','o','v','e',0};
static const WCHAR add_sourceW[] = {'A','d','d','S','o','u','r','c','e',0};
static const WCHAR set_target_pathW[] = {'S','e','t','T','a','r','g','e','t','P','a','t','h',0};
static const WCHAR resetW[] = {'R','e','s','e','t',0};
static const WCHAR set_install_levelW[] = {'S','e','t','I','n','s','t','a','l','l','L','e','v','e','l',0};
static const WCHAR directory_list_upW[] = {'D','i','r','e','c','t','o','r','y','L','i','s','t','U','p',0};
static const WCHAR selection_browseW[] = {'S','e','l','e','c','t','i','o','n','B','r','o','w','s','e',0};
static const WCHAR reinstall_modeW[] = {'R','e','i','n','s','t','a','l','l','M','o','d','e',0};
static const WCHAR reinstallW[] = {'R','e','i','n','s','t','a','l','l',0};
static const WCHAR validate_product_idW[] = {'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0};

static const struct control_events control_events[] =
{
    { end_dialogW, ControlEvent_EndDialog },
    { new_dialogW, ControlEvent_NewDialog },
    { spawn_dialogW, ControlEvent_SpawnDialog },
    { spawn_wait_dialogW, ControlEvent_SpawnWaitDialog },
    { do_actionW, ControlEvent_DoAction },
    { add_localW, ControlEvent_AddLocal },
    { removeW, ControlEvent_Remove },
    { add_sourceW, ControlEvent_AddSource },
    { set_target_pathW, ControlEvent_SetTargetPath },
    { resetW, ControlEvent_Reset },
    { set_install_levelW, ControlEvent_SetInstallLevel },
    { directory_list_upW, ControlEvent_DirectoryListUp },
    { selection_browseW, ControlEvent_SpawnDialog },
    { reinstall_modeW, ControlEvent_ReinstallMode },
    { reinstallW, ControlEvent_Reinstall },
    { validate_product_idW, ControlEvent_ValidateProductID },
    { NULL, NULL }
};

UINT ControlEvent_HandleControlEvent( MSIPACKAGE *package, LPCWSTR event,
                                      LPCWSTR argument, msi_dialog *dialog )
{
    unsigned int i;

    TRACE("handling control event %s\n", debugstr_w(event));

    if (!event) return ERROR_SUCCESS;

    for (i = 0; control_events[i].event; i++)
    {
        if (!strcmpW( control_events[i].event, event ))
            return control_events[i].handler( package, argument, dialog );
    }
    FIXME("unhandled control event %s arg(%s)\n", debugstr_w(event), debugstr_w(argument));
    return ERROR_SUCCESS;
}
