/*
 * 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
#define PROCQUIT_TIMEOUT    20000

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;
    }

    /* wait for app to quit on its own for a while */
    ret = WaitForSingleObject( process_handle, PROCQUIT_TIMEOUT );
    CloseHandle( process_handle );
    if (ret == WAIT_TIMEOUT)
    {
        /* it didn't quit by itself in time, so terminate it with extreme prejudice */
        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 );
        }
    }
}
