/*
 * HAL devices support
 *
 * Copyright 2006 Alexandre Julliard
 *
 * 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 "config.h"
#include "wine/port.h"

#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/time.h>

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "excpt.h"

#include "wine/library.h"
#include "wine/exception.h"
#include "wine/debug.h"
#include "explorer_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(explorer);

#ifdef SONAME_LIBHAL

#include <dbus/dbus.h>
#include <hal/libhal.h>

#define DBUS_FUNCS \
    DO_FUNC(dbus_bus_get); \
    DO_FUNC(dbus_connection_close); \
    DO_FUNC(dbus_connection_read_write_dispatch); \
    DO_FUNC(dbus_error_init); \
    DO_FUNC(dbus_error_free); \
    DO_FUNC(dbus_error_is_set)

#define HAL_FUNCS \
    DO_FUNC(libhal_ctx_free); \
    DO_FUNC(libhal_ctx_init); \
    DO_FUNC(libhal_ctx_new); \
    DO_FUNC(libhal_ctx_set_dbus_connection); \
    DO_FUNC(libhal_ctx_set_device_added); \
    DO_FUNC(libhal_ctx_set_device_property_modified); \
    DO_FUNC(libhal_ctx_set_device_removed); \
    DO_FUNC(libhal_ctx_shutdown); \
    DO_FUNC(libhal_device_get_property_bool); \
    DO_FUNC(libhal_device_get_property_string); \
    DO_FUNC(libhal_device_add_property_watch); \
    DO_FUNC(libhal_device_remove_property_watch); \
    DO_FUNC(libhal_free_string); \
    DO_FUNC(libhal_free_string_array); \
    DO_FUNC(libhal_get_all_devices)

#define DO_FUNC(f) static typeof(f) * p_##f
DBUS_FUNCS;
HAL_FUNCS;
#undef DO_FUNC

static BOOL load_functions(void)
{
    void *hal_handle;
    char error[128];

    /* Load libhal with RTLD_GLOBAL so that the dbus symbols are available.
     * We can't load libdbus directly since libhal may have been built against a
     * different version but with the same soname. Binary compatibility is for wimps. */

    if (!(hal_handle = wine_dlopen(SONAME_LIBHAL, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error))))
        goto failed;

#define DO_FUNC(f) if (!(p_##f = wine_dlsym( RTLD_DEFAULT, #f, error, sizeof(error) ))) goto failed
    DBUS_FUNCS;
#undef DO_FUNC

#define DO_FUNC(f) if (!(p_##f = wine_dlsym( hal_handle, #f, error, sizeof(error) ))) goto failed
    HAL_FUNCS;
#undef DO_FUNC

    return TRUE;

failed:
    WINE_WARN( "failed to load HAL support: %s\n", error );
    return FALSE;
}

static WINE_EXCEPTION_FILTER(assert_fault)
{
    if (GetExceptionCode() == EXCEPTION_WINE_ASSERTION) return EXCEPTION_EXECUTE_HANDLER;
    return EXCEPTION_CONTINUE_SEARCH;
}

/* HAL callback for new device */
static void new_device( LibHalContext *ctx, const char *udi )
{
    DBusError error;
    char *parent, *mount_point, *device, *type;

    p_dbus_error_init( &error );

    if (!(device = p_libhal_device_get_property_string( ctx, udi, "block.device", &error )))
        goto done;

    if (!(mount_point = p_libhal_device_get_property_string( ctx, udi, "volume.mount_point", &error )))
        goto done;

    if (!(parent = p_libhal_device_get_property_string( ctx, udi, "info.parent", &error )))
        goto done;

    if (!p_libhal_device_get_property_bool( ctx, parent, "storage.removable", &error ))
        goto done;

    if (!(type = p_libhal_device_get_property_string( ctx, parent, "storage.drive_type", &error )))
        p_dbus_error_free( &error );  /* ignore error */

    add_dos_device( udi, device, mount_point, type );

    if (type) p_libhal_free_string( type );
    p_libhal_free_string( parent );
    p_libhal_free_string( device );
    p_libhal_free_string( mount_point );

    /* add property watch for mount point */
    p_libhal_device_add_property_watch( ctx, udi, &error );

done:
    p_dbus_error_free( &error );
}

/* HAL callback for removed device */
static void removed_device( LibHalContext *ctx, const char *udi )
{
    DBusError error;

    WINE_TRACE( "removed %s\n", wine_dbgstr_a(udi) );

    if (remove_dos_device( udi ))
    {
        p_dbus_error_init( &error );
        p_libhal_device_remove_property_watch( ctx, udi, &error );
        p_dbus_error_free( &error );
    }
}

/* HAL callback for property changes */
static void property_modified (LibHalContext *ctx, const char *udi,
                               const char *key, dbus_bool_t is_removed, dbus_bool_t is_added)
{
    WINE_TRACE( "udi %s key %s %s\n", wine_dbgstr_a(udi), wine_dbgstr_a(key),
                is_added ? "added" : is_removed ? "removed" : "modified" );

    if (!strcmp( key, "volume.mount_point" )) new_device( ctx, udi );
}


static DWORD WINAPI hal_thread( void *arg )
{
    DBusError error;
    DBusConnection *dbc;
    LibHalContext *ctx;
    int i, num;
    char **list;

    if (!(ctx = p_libhal_ctx_new())) return 1;

    p_dbus_error_init( &error );
    if (!(dbc = p_dbus_bus_get( DBUS_BUS_SYSTEM, &error )))
    {
        WINE_WARN( "failed to get system dbus connection: %s\n", error.message );
        p_dbus_error_free( &error );
        return 1;
    }

    p_libhal_ctx_set_dbus_connection( ctx, dbc );
    p_libhal_ctx_set_device_added( ctx, new_device );
    p_libhal_ctx_set_device_removed( ctx, removed_device );
    p_libhal_ctx_set_device_property_modified( ctx, property_modified );

    if (!p_libhal_ctx_init( ctx, &error ))
    {
        WINE_WARN( "HAL context init failed: %s\n", error.message );
        p_dbus_error_free( &error );
        return 1;
    }

    /* retrieve all existing devices */
    if (!(list = p_libhal_get_all_devices( ctx, &num, &error ))) p_dbus_error_free( &error );
    else
    {
        for (i = 0; i < num; i++) new_device( ctx, list[i] );
        p_libhal_free_string_array( list );
    }

    __TRY
    {
        while (p_dbus_connection_read_write_dispatch( dbc, -1 )) /* nothing */ ;
    }
    __EXCEPT( assert_fault )
    {
        WINE_WARN( "dbus assertion failure, disabling HAL support\n" );
        return 1;
    }
    __ENDTRY;

    p_libhal_ctx_shutdown( ctx, &error );
    p_dbus_error_free( &error );  /* just in case */
    p_dbus_connection_close( dbc );
    p_libhal_ctx_free( ctx );
    return 0;
}

void initialize_hal(void)
{
    HANDLE handle;

    if (!load_functions()) return;
    if (!(handle = CreateThread( NULL, 0, hal_thread, NULL, 0, NULL ))) return;
    CloseHandle( handle );
}

#else  /* SONAME_LIBHAL */

void initialize_hal(void)
{
    WINE_TRACE( "Skipping, HAL support not compiled in\n" );
}

#endif  /* SONAME_LIBHAL */
