/*
 * Server-side debugger functions
 *
 * Copyright (C) 1999 Alexandre Julliard
 */

#include <assert.h>
#include <string.h>

#include "winbase.h"
#include "winerror.h"

#include "handle.h"
#include "process.h"
#include "thread.h"
#include "request.h"

struct debug_event
{
    struct debug_event    *next;    /* event queue */
    struct debug_event    *prev;
    struct thread         *thread;  /* thread which sent this event */
    int                    sent;    /* already sent to the debugger? */
    int                    code;    /* event code */
    union debug_event_data data;    /* event data */
};

struct debug_ctx
{
    struct thread       *owner;       /* thread owning this debug context */   
    int                  waiting;     /* is thread waiting for an event? */
    struct timeout_user *timeout;     /* timeout user for wait timeout */
    struct debug_event  *event_head;  /* head of pending events queue */
    struct debug_event  *event_tail;  /* tail of pending events queue */
};

/* size of the event data */
static const int event_sizes[] =
{
    0,
    sizeof(struct debug_event_exception),       /* EXCEPTION_DEBUG_EVENT */
    sizeof(struct debug_event_create_thread),   /* CREATE_THREAD_DEBUG_EVENT */
    sizeof(struct debug_event_create_process),  /* CREATE_PROCESS_DEBUG_EVENT */
    sizeof(struct debug_event_exit),            /* EXIT_THREAD_DEBUG_EVENT */
    sizeof(struct debug_event_exit),            /* EXIT_PROCESS_DEBUG_EVENT */
    sizeof(struct debug_event_load_dll),        /* LOAD_DLL_DEBUG_EVENT */
    sizeof(struct debug_event_unload_dll),      /* UNLOAD_DLL_DEBUG_EVENT */
    sizeof(struct debug_event_output_string),   /* OUTPUT_DEBUG_STRING_EVENT */
    sizeof(struct debug_event_rip_info)         /* RIP_EVENT */
};


/* initialise the fields that do not need to be filled by the client */
static int fill_debug_event( struct thread *debugger, struct thread *thread,
                             struct debug_event *event )
{
    int handle;

    /* some events need special handling */
    switch(event->code)
    {
    case CREATE_THREAD_DEBUG_EVENT:
        if ((event->data.create_thread.handle = alloc_handle( debugger->process, thread,
                  THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE )) == -1)
            return 0;
        break;
    case CREATE_PROCESS_DEBUG_EVENT:
        if ((handle = event->data.create_process.file) != -1)
        {
            if ((handle = duplicate_handle( thread->process, handle, debugger->process,
                                            GENERIC_READ, FALSE, 0 )) == -1)
                return 0;
            event->data.create_process.file = handle;
        }
        if ((event->data.create_process.process = alloc_handle( debugger->process, thread->process,
                                              PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE )) == -1)
        {
            if (handle != -1) close_handle( debugger->process, handle );
            return 0;
        }
        if ((event->data.create_process.thread = alloc_handle( debugger->process, thread,
                  THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE )) == -1)
        {
            if (handle != -1) close_handle( debugger->process, handle );
            close_handle( debugger->process, event->data.create_process.process );
            return 0;
        }
        break;
    case LOAD_DLL_DEBUG_EVENT:
        if ((handle = event->data.load_dll.handle) != -1)
        {
            if ((handle = duplicate_handle( thread->process, handle, debugger->process,
                                            GENERIC_READ, FALSE, 0 )) == -1)
                return 0;
            event->data.load_dll.handle = handle;
        }
        break;
    }
    return 1;
}

/* free a debug event structure */
static void free_event( struct debug_event *event )
{
    switch(event->code)
    {
    case CREATE_THREAD_DEBUG_EVENT:
        close_handle( event->thread->process, event->data.create_thread.handle );
        break;
    case CREATE_PROCESS_DEBUG_EVENT:
        if (event->data.create_process.file != -1)
            close_handle( event->thread->process, event->data.create_process.file );
        close_handle( event->thread->process, event->data.create_process.thread );
        close_handle( event->thread->process, event->data.create_process.process );
        break;
    case LOAD_DLL_DEBUG_EVENT:
        if (event->data.load_dll.handle != -1)
            close_handle( event->thread->process, event->data.load_dll.handle );
        break;
    }
    event->thread->debug_event = NULL;
    release_object( event->thread );
    free( event );
}

/* unlink the first event from the queue */
static void unlink_event( struct debug_ctx *debug_ctx, struct debug_event *event )
{
    if (event->prev) event->prev->next = event->next;
    else debug_ctx->event_head = event->next;
    if (event->next) event->next->prev = event->prev;
    else debug_ctx->event_tail = event->prev;
    event->next = event->prev = NULL;
}

/* link an event at the end of the queue */
static void link_event( struct debug_ctx *debug_ctx, struct debug_event *event )
{
    event->next = NULL;
    event->prev = debug_ctx->event_tail;
    if (event->prev) event->prev->next = event;
    else debug_ctx->event_head = event;
    debug_ctx->event_tail = event;
}

/* send the first queue event as a reply */
static void build_event_reply( struct debug_ctx *debug_ctx )
{
    struct debug_event *event = debug_ctx->event_head;
    struct thread *thread = event->thread;
    struct wait_debug_event_request *req = get_req_ptr( debug_ctx->owner );

    assert( event );
    assert( debug_ctx->waiting );

    unlink_event( debug_ctx, event );
    event->sent = 1;
    req->code = event->code;
    req->pid  = thread->process;
    req->tid  = thread;
    debug_ctx->waiting = 0;
    if (debug_ctx->timeout)
    {
        remove_timeout_user( debug_ctx->timeout );
        debug_ctx->timeout = NULL;
    }
    debug_ctx->owner->error = 0;
    memcpy( req + 1, &event->data, event_sizes[event->code] );
}

/* timeout callback while waiting for a debug event */
static void wait_event_timeout( void *ctx )
{
    struct debug_ctx *debug_ctx = (struct debug_ctx *)ctx;
    struct wait_debug_event_request *req = get_req_ptr( debug_ctx->owner );

    assert( debug_ctx->waiting );

    req->code = 0;
    req->pid  = 0;
    req->tid  = 0;
    debug_ctx->waiting = 0;
    debug_ctx->timeout = NULL;
    debug_ctx->owner->error = WAIT_TIMEOUT;
    send_reply( debug_ctx->owner );
}

/* wait for a debug event (or send a reply at once if one is pending) */
static int wait_for_debug_event( int timeout )
{
    struct debug_ctx *debug_ctx = current->debug_ctx;
    struct timeval when;

    if (!debug_ctx)  /* current thread is not a debugger */
    {
        set_error( ERROR_ACCESS_DENIED ); /* FIXME */
        return 0;
    }
    assert( !debug_ctx->waiting );
    if (debug_ctx->event_head)  /* already have a pending event */
    {
        debug_ctx->waiting = 1;
        build_event_reply( debug_ctx );
        return 1;
    }
    if (!timeout)  /* no event and we don't want to wait */
    {
        set_error( WAIT_TIMEOUT );
        return 0;
    }
    if (timeout != -1)  /* start the timeout */
    {
        make_timeout( &when, timeout );
        if (!(debug_ctx->timeout = add_timeout_user( &when, wait_event_timeout, debug_ctx )))
            return 0;
    }
    debug_ctx->waiting = 1;
    current->state = SLEEPING;
    return 1;
}

/* continue a debug event */
static int continue_debug_event( struct process *process, struct thread *thread, int status )
{
    struct debug_event *event = thread->debug_event;

    if (process->debugger != current || !event || !event->sent)
    {
        /* not debugging this process, or no event pending */
        set_error( ERROR_ACCESS_DENIED );  /* FIXME */
        return 0;
    }
    if (thread->state != TERMINATED)
    {
        /* only send a reply if the thread is still there */
        /* (we can get a continue on an exit thread/process event) */
        struct send_debug_event_request *req = get_req_ptr( thread );
        req->status = status;
        send_reply( thread );
    }
    free_event( event );
    resume_process( process );
    return 1;
}

/* queue a debug event for a debugger */
static struct debug_event *queue_debug_event( struct thread *debugger, struct thread *thread,
                                              int code, void *data )
{
    struct debug_ctx *debug_ctx = debugger->debug_ctx;
    struct debug_event *event;

    assert( debug_ctx );
    /* cannot queue a debug event for myself */
    assert( debugger->process != thread->process );

    /* build the event */
    if (!(event = mem_alloc( sizeof(*event) - sizeof(event->data) + event_sizes[code] )))
        return NULL;
    event->sent   = 0;
    event->code   = code;
    event->thread = (struct thread *)grab_object( thread );
    memcpy( &event->data, data, event_sizes[code] );

    if (!fill_debug_event( debugger, thread, event ))
    {
        release_object( event->thread );
        free( event );
        return NULL;
    }

    if (thread->debug_event)
    {
        /* only exit events can replace others */
        assert( code == EXIT_THREAD_DEBUG_EVENT || code == EXIT_PROCESS_DEBUG_EVENT );
        if (!thread->debug_event->sent) unlink_event( debug_ctx, thread->debug_event );
        free_event( thread->debug_event );
    }

    link_event( debug_ctx, event );
    thread->debug_event = event;
    suspend_process( thread->process );
    if (debug_ctx->waiting)
    {
        build_event_reply( debug_ctx );
        send_reply( debug_ctx->owner );
    }
    return event;
}

/* attach a process to a debugger thread */
int debugger_attach( struct process *process, struct thread *debugger )
{
    struct debug_ctx *debug_ctx;
    struct thread *thread;

    if (process->debugger)  /* already being debugged */
    {
        set_error( ERROR_ACCESS_DENIED );
        return 0;
    }
    /* make sure we don't create a debugging loop */
    for (thread = debugger; thread; thread = thread->process->debugger)
        if (thread->process == process)
        {
            set_error( ERROR_ACCESS_DENIED );
            return 0;
        }

    if (!debugger->debug_ctx)  /* need to allocate a context */
    {
        assert( !debugger->debug_first );
        if (!(debug_ctx = mem_alloc( sizeof(*debug_ctx) ))) return 0;
        debug_ctx->owner      = current;
        debug_ctx->waiting    = 0;
        debug_ctx->timeout    = NULL;
        debug_ctx->event_head = NULL;
        debug_ctx->event_tail = NULL;
        debugger->debug_ctx = debug_ctx;
    }
    process->debugger   = debugger;
    process->debug_prev = NULL;
    process->debug_next = debugger->debug_first;
    debugger->debug_first = process;
    return 1;
}

/* detach a process from its debugger thread */
static void debugger_detach( struct process *process )
{
    struct thread *debugger = process->debugger;

    assert( debugger );

    if (process->debug_next) process->debug_next->debug_prev = process->debug_prev;
    if (process->debug_prev) process->debug_prev->debug_next = process->debug_next;
    else debugger->debug_first = process;
    process->debugger = NULL;
}

/* a thread is exiting */
void debug_exit_thread( struct thread *thread, int exit_code )
{
    struct thread *debugger = current->process->debugger;
    struct debug_ctx *debug_ctx = thread->debug_ctx;

    if (debugger)  /* being debugged -> send an event to the debugger */
    {
        struct debug_event_exit event;
        event.exit_code = exit_code;
        if (!thread->proc_next && !thread->proc_prev)
        {
            assert( thread->process->thread_list == thread );
            /* this is the last thread, send an exit process event and cleanup */
            queue_debug_event( debugger, current, EXIT_PROCESS_DEBUG_EVENT, &event );
            debugger_detach( thread->process );
        }
        else queue_debug_event( debugger, current, EXIT_THREAD_DEBUG_EVENT, &event );
    }

    if (debug_ctx)  /* this thread is a debugger */
    {
        struct debug_event *event;

        /* kill all debugged processes */
        while (thread->debug_first) kill_process( thread->debug_first, exit_code );
        /* free all pending events */
        while ((event = debug_ctx->event_head) != NULL)
        {
            unlink_event( debug_ctx, event );
            free_event( event );
        }
        /* remove the timeout */
        if (debug_ctx->timeout) remove_timeout_user( debug_ctx->timeout );
        thread->debug_ctx = NULL;
        free( debug_ctx );
    }
}

/* Wait for a debug event */
DECL_HANDLER(wait_debug_event)
{
    if (!wait_for_debug_event( req->timeout ))
    {
        req->code = 0;
        req->pid  = NULL;
        req->tid  = NULL;
    }
}

/* Continue a debug event */
DECL_HANDLER(continue_debug_event)
{
    struct process *process = get_process_from_id( req->pid );
    if (process)
    {
        struct thread *thread = get_thread_from_id( req->tid );
        if (thread)
        {
            continue_debug_event( process, thread, req->status );
            release_object( thread );
        }
        release_object( process );
    }
}

/* Start debugging an existing process */
DECL_HANDLER(debug_process)
{
    struct process *process = get_process_from_id( req->pid );
    if (process)
    {
        debugger_attach( process, current );
        /* FIXME: should notice the debugged process somehow */
        release_object( process );
    }
}

/* Send a debug event */
DECL_HANDLER(send_debug_event)
{
    struct thread *debugger = current->process->debugger;

    assert( !current->debug_event );
    if ((req->code <= 0) || (req->code > RIP_EVENT))
    {
        fatal_protocol_error( current, "send_debug_event: bad code %d\n", req->code );
        return;
    }
    req->status = 0;
    if (debugger && queue_debug_event( debugger, current, req->code, req + 1 ))
    {
        /* wait for continue_debug_event */
        current->state = SLEEPING;
    }
}
