/*
 * Win32 file change notification functions
 *
 * Copyright 1998 Ulrich Weigand
 */

#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include "windows.h"
#include "winbase.h"
#include "winerror.h"
#include "process.h"
#include "thread.h"
#include "heap.h"
#include "debug.h"

static BOOL32 CHANGE_Signaled( K32OBJ *obj, DWORD thread_id );
static BOOL32 CHANGE_Satisfied( K32OBJ *obj, DWORD thread_id );
static void CHANGE_AddWait( K32OBJ *obj, DWORD thread_id );
static void CHANGE_RemoveWait( K32OBJ *obj, DWORD thread_id );
static void CHANGE_Destroy( K32OBJ *obj );

const K32OBJ_OPS CHANGE_Ops =
{
    CHANGE_Signaled,    /* signaled */
    CHANGE_Satisfied,   /* satisfied */
    CHANGE_AddWait,     /* add_wait */
    CHANGE_RemoveWait,  /* remove_wait */
    NULL,               /* read */
    NULL,               /* write */
    CHANGE_Destroy      /* destroy */
};

/* The change notification object */
typedef struct
{
    K32OBJ       header;

    LPSTR        lpPathName;
    BOOL32       bWatchSubtree;
    DWORD        dwNotifyFilter;

    THREAD_QUEUE wait_queue;    
    BOOL32       notify;

} CHANGE_OBJECT;

/***********************************************************************
 *           CHANGE_Signaled
 */
static BOOL32 CHANGE_Signaled( K32OBJ *obj, DWORD thread_id )
{
    CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
    assert( obj->type == K32OBJ_CHANGE );
    return change->notify;
}

/***********************************************************************
 *           CHANGE_Satisfied
 *
 * Wait on this object has been satisfied.
 */
static BOOL32 CHANGE_Satisfied( K32OBJ *obj, DWORD thread_id )
{
    assert( obj->type == K32OBJ_CHANGE );
    return FALSE;  /* Not abandoned */
}

/***********************************************************************
 *           CHANGE_AddWait
 *
 * Add thread to object wait queue.
 */
static void CHANGE_AddWait( K32OBJ *obj, DWORD thread_id )
{
    CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
    assert( obj->type == K32OBJ_CHANGE );
    THREAD_AddQueue( &change->wait_queue, THREAD_ID_TO_THDB(thread_id) );
}

/***********************************************************************
 *           CHANGE_RemoveWait
 *
 * Remove thread from object wait queue.
 */
static void CHANGE_RemoveWait( K32OBJ *obj, DWORD thread_id )
{
    CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
    assert( obj->type == K32OBJ_CHANGE );
    THREAD_RemoveQueue( &change->wait_queue, THREAD_ID_TO_THDB(thread_id) );
}

/****************************************************************************
 *		CHANGE_Destroy
 */
static void CHANGE_Destroy( K32OBJ *obj )
{
    CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
    assert( obj->type == K32OBJ_CHANGE );

    if ( change->lpPathName )
    {
        HeapFree( SystemHeap, 0, change->lpPathName );
        change->lpPathName = NULL;
    }

    obj->type = K32OBJ_UNKNOWN;
    HeapFree( SystemHeap, 0, change );
}

/****************************************************************************
 *		FindFirstChangeNotification32A (KERNEL32.248)
 */
HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName,
                                                BOOL32 bWatchSubtree,
                                                DWORD dwNotifyFilter ) 
{
    HANDLE32 handle;
    CHANGE_OBJECT *change;

    change = HeapAlloc( SystemHeap, 0, sizeof(CHANGE_OBJECT) );
    if (!change) return INVALID_HANDLE_VALUE32;

    change->header.type = K32OBJ_CHANGE;
    change->header.refcount = 1;

    change->lpPathName = HEAP_strdupA( SystemHeap, 0, lpPathName );
    change->bWatchSubtree = bWatchSubtree;
    change->dwNotifyFilter = dwNotifyFilter;

    change->wait_queue = NULL;
    change->notify = FALSE;

    handle = HANDLE_Alloc( PROCESS_Current(), &change->header, 
                           FILE_ALL_ACCESS /*FIXME*/, TRUE, -1 );
    /* If the allocation failed, the object is already destroyed */
    if (handle == INVALID_HANDLE_VALUE32) change = NULL;
    return handle;
}

/****************************************************************************
 *		FindFirstChangeNotification32W (KERNEL32.249)
 */
HANDLE32 WINAPI FindFirstChangeNotification32W( LPCWSTR lpPathName,
                                                BOOL32 bWatchSubtree,
                                                DWORD dwNotifyFilter) 
{
    LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpPathName );
    HANDLE32 ret = FindFirstChangeNotification32A( nameA, bWatchSubtree, 
                                                          dwNotifyFilter );
    if (nameA) HeapFree( GetProcessHeap(), 0, nameA );
    return ret;
}

/****************************************************************************
 *		FindNextChangeNotification (KERNEL32.252)
 */
BOOL32 WINAPI FindNextChangeNotification( HANDLE32 handle ) 
{
    CHANGE_OBJECT *change;

    SYSTEM_LOCK();
    if (!(change = (CHANGE_OBJECT *)HANDLE_GetObjPtr( PROCESS_Current(),
                                                      handle, K32OBJ_CHANGE, 
                                                      0 /*FIXME*/, NULL )) )
    {
        SYSTEM_UNLOCK();
        return FALSE;
    }

    change->notify = FALSE;
    K32OBJ_DecCount( &change->header );
    SYSTEM_UNLOCK();
    return TRUE;
}

/****************************************************************************
 *		FindCloseChangeNotification (KERNEL32.247)
 */
BOOL32 WINAPI FindCloseChangeNotification( HANDLE32 handle) 
{
    return CloseHandle( handle );
}

