/*
 * Copyright (C) 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 <stdarg.h>
#include <stdlib.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "tlhelp32.h"

#include "wine/debug.h"

#include "resource.h"

WINE_DEFAULT_DEBUG_CHANNEL(wineboot);

#define MESSAGE_TIMEOUT     5000

struct window_info
{
    HWND  hwnd;
    DWORD pid;
    DWORD tid;
};

static UINT win_count;
static UINT win_max;
static struct window_info *windows;
static DWORD desktop_pid;

/* store a new window; callback for EnumWindows */
static BOOL CALLBACK enum_proc( HWND hwnd, LPARAM lp )
{
    if (win_count >= win_max)
    {
        UINT new_count = win_max * 2;
        struct window_info *new_win = HeapReAlloc( GetProcessHeap(), 0, windows,
                                                   new_count * sizeof(windows[0]) );
        if (!new_win) return FALSE;
        windows = new_win;
        win_max = new_count;
    }
    windows[win_count].hwnd = hwnd;
    windows[win_count].tid = GetWindowThreadProcessId( hwnd, &windows[win_count].pid );
    win_count++;
    return TRUE;
}

/* compare two window info structures; callback for qsort */
static int cmp_window( const void *ptr1, const void *ptr2 )
{
    const struct window_info *info1 = ptr1;
    const struct window_info *info2 = ptr2;
    int ret = info1->pid - info2->pid;
    if (!ret) ret = info1->tid - info2->tid;
    return ret;
}

/* build the list of all windows (FIXME: handle multiple desktops) */
static BOOL get_all_windows(void)
{
    win_count = 0;
    win_max = 16;
    windows = HeapAlloc( GetProcessHeap(), 0, win_max * sizeof(windows[0]) );
    if (!windows) return FALSE;
    if (!EnumWindows( enum_proc, 0 )) return FALSE;
    /* sort windows by processes */
    qsort( windows, win_count, sizeof(windows[0]), cmp_window );
    return TRUE;
}

struct callback_data
{
    UINT window_count;
    BOOL timed_out;
    LRESULT result;
};

static void CALLBACK end_session_message_callback( HWND hwnd, UINT msg, ULONG_PTR data, LRESULT lresult )
{
    struct callback_data *cb_data = (struct callback_data *)data;

    WINE_TRACE( "received response %s hwnd %p lresult %ld\n",
                msg == WM_QUERYENDSESSION ? "WM_QUERYENDSESSION" : (msg == WM_ENDSESSION ? "WM_ENDSESSION" : "Unknown"),
                hwnd, lresult );

    /* we only care if a WM_QUERYENDSESSION response is FALSE */
    cb_data->result = cb_data->result && lresult;

    /* cheap way of ref-counting callback_data whilst freeing memory at correct
     * time */
    if (!(cb_data->window_count--) && cb_data->timed_out)
        HeapFree( GetProcessHeap(), 0, cb_data );
}

struct endtask_dlg_data
{
    struct window_info *win;
    BOOL cancelled;
};

static INT_PTR CALLBACK endtask_dlg_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
    struct endtask_dlg_data *data;
    HANDLE handle;

    switch (msg)
    {
    case WM_INITDIALOG:
        SetWindowLongPtrW( hwnd, DWLP_USER, lparam );
        data = (struct endtask_dlg_data *)lparam;
        ShowWindow( hwnd, SW_SHOWNORMAL );
        return TRUE;
    case WM_COMMAND:
        data = (struct endtask_dlg_data *)GetWindowLongPtrW( hwnd, DWLP_USER );
        switch (wparam)
        {
        case MAKEWPARAM(IDOK, BN_CLICKED):
            handle = OpenProcess( PROCESS_TERMINATE, FALSE, data->win[0].pid );
            if (handle)
            {
                WINE_TRACE( "terminating process %04x\n", data->win[0].pid );
                TerminateProcess( handle, 0 );
                CloseHandle( handle );
            }
            return TRUE;
        case MAKEWPARAM(IDCANCEL, BN_CLICKED):
            data->cancelled = TRUE;
            return TRUE;
        }
        break;
    }
    return FALSE;
}

/* Sends a message to a set of windows, displaying a dialog if the window
 * doesn't respond to the message within a set amount of time.
 * If the process has already been terminated, the function returns -1.
 * If the user or application cancels the process, the function returns 0.
 * Otherwise the function returns 0. */
static LRESULT send_messages_with_timeout_dialog(
    struct window_info *win, UINT count, HANDLE process_handle,
    UINT msg, WPARAM wparam, LPARAM lparam )
{
    unsigned int i;
    DWORD ret;
    DWORD start_time;
    struct callback_data *cb_data;
    HWND hwnd_endtask = NULL;
    struct endtask_dlg_data dlg_data;
    LRESULT result;

    cb_data = HeapAlloc( GetProcessHeap(), 0, sizeof(*cb_data) );
    if (!cb_data)
        return 1;

    cb_data->result = TRUE; /* we only care if a WM_QUERYENDSESSION response is FALSE */
    cb_data->timed_out = FALSE;
    cb_data->window_count = count;

    dlg_data.win = win;
    dlg_data.cancelled = FALSE;

    for (i = 0; i < count; i++)
    {
        if (!SendMessageCallbackW( win[i].hwnd, msg, wparam, lparam,
                                   end_session_message_callback, (ULONG_PTR)cb_data ))
            cb_data->window_count --;
    }

    start_time = GetTickCount();
    while (TRUE)
    {
        DWORD current_time = GetTickCount();

        ret = MsgWaitForMultipleObjects( 1, &process_handle, FALSE,
                                         MESSAGE_TIMEOUT - (current_time - start_time),
                                         QS_ALLINPUT );
        if (ret == WAIT_OBJECT_0) /* process exited */
        {
            HeapFree( GetProcessHeap(), 0, cb_data );
            result = 1;
            goto cleanup;
        }
        else if (ret == WAIT_OBJECT_0 + 1) /* window message */
        {
            MSG msg;
            while(PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE ))
            {
                if (!hwnd_endtask || !IsDialogMessageW( hwnd_endtask, &msg ))
                {
                    TranslateMessage( &msg );
                    DispatchMessageW( &msg );
                }
            }
            if (!cb_data->window_count)
            {
                result = cb_data->result;
                HeapFree( GetProcessHeap(), 0, cb_data );
                if (!result)
                    goto cleanup;
                break;
            }
            if (dlg_data.cancelled)
            {
                cb_data->timed_out = TRUE;
                result = 0;
                goto cleanup;
            }
        }
        else if ((ret == WAIT_TIMEOUT) && !hwnd_endtask)
        {
            hwnd_endtask = CreateDialogParamW( GetModuleHandleW(NULL),
                                               MAKEINTRESOURCEW(IDD_ENDTASK),
                                               NULL, endtask_dlg_proc,
                                               (LPARAM)&dlg_data );
        }
        else break;
    }

    result = 1;

cleanup:
    if (hwnd_endtask) DestroyWindow( hwnd_endtask );
    return result;
}

/* send WM_QUERYENDSESSION and WM_ENDSESSION to all windows of a given process */
static DWORD_PTR send_end_session_messages( struct window_info *win, UINT count, UINT flags )
{
    LRESULT result, end_session;
    HANDLE process_handle;
    DWORD ret;

    /* FIXME: Use flags to implement EWX_FORCEIFHUNG! */
    /* don't kill the desktop process */
    if (win[0].pid == desktop_pid) return 1;

    process_handle = OpenProcess( SYNCHRONIZE, FALSE, win[0].pid );
    if (!process_handle)
        return 1;

    end_session = send_messages_with_timeout_dialog( win, count, process_handle,
                                                     WM_QUERYENDSESSION, 0, 0 );
    if (end_session == -1)
    {
        CloseHandle( process_handle );
        return 1;
    }

    result = send_messages_with_timeout_dialog( win, count, process_handle,
                                                WM_ENDSESSION, end_session, 0 );
    if (end_session == 0)
    {
        CloseHandle( process_handle );
        return 0;
    }
    if (result == -1)
    {
        CloseHandle( process_handle );
        return 1;
    }

    /* Check whether the app quit on its own */
    ret = WaitForSingleObject( process_handle, 0 );
    CloseHandle( process_handle );
    if (ret == WAIT_TIMEOUT)
    {
        /* If not, it returned from all WM_ENDSESSION and is finished cleaning
         * up, so we can safely kill the process. */
        HANDLE handle = OpenProcess( PROCESS_TERMINATE, FALSE, win[0].pid );
        if (handle)
        {
            WINE_TRACE( "terminating process %04x\n", win[0].pid );
            TerminateProcess( handle, 0 );
            CloseHandle( handle );
        }
    }
    return 1;
}

/* close all top-level windows and terminate processes cleanly */
BOOL shutdown_close_windows( BOOL force )
{
    UINT send_flags = force ? SMTO_ABORTIFHUNG : SMTO_NORMAL;
    DWORD_PTR result = 1;
    UINT i, n;

    if (!get_all_windows()) return FALSE;

    GetWindowThreadProcessId( GetDesktopWindow(), &desktop_pid );

    for (i = n = 0; result && i < win_count; i++, n++)
    {
        if (n && windows[i-1].pid != windows[i].pid)
        {
            result = send_end_session_messages( windows + i - n, n, send_flags );
            n = 0;
        }
    }
    if (n && result)
        result = send_end_session_messages( windows + win_count - n, n, send_flags );

    HeapFree( GetProcessHeap(), 0, windows );

    return (result != 0);
}

/* forcibly kill all processes without any cleanup */
void kill_processes( BOOL kill_desktop )
{
    BOOL res;
    UINT killed;
    HANDLE handle, snapshot;
    PROCESSENTRY32W process;

    GetWindowThreadProcessId( GetDesktopWindow(), &desktop_pid );

    do
    {
        if (!(snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ))) break;

        killed = 0;
        process.dwSize = sizeof(process);
        for (res = Process32FirstW( snapshot, &process ); res; res = Process32NextW( snapshot, &process ))
        {
            if (process.th32ProcessID == GetCurrentProcessId()) continue;
            if (process.th32ProcessID == desktop_pid) continue;
            WINE_TRACE("killing process %04x %s\n",
                       process.th32ProcessID, wine_dbgstr_w(process.szExeFile) );
            if (!(handle = OpenProcess( PROCESS_TERMINATE, FALSE, process.th32ProcessID )))
                continue;
            if (TerminateProcess( handle, 0 )) killed++;
            CloseHandle( handle );
        }
        CloseHandle( snapshot );
    } while (killed > 0);

    if (desktop_pid && kill_desktop)  /* do this last */
    {
        if ((handle = OpenProcess( PROCESS_TERMINATE, FALSE, desktop_pid )))
        {
            TerminateProcess( handle, 0 );
            CloseHandle( handle );
        }
    }
}
