/*
 * 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 thread *debugger, struct debug_event *event )
{
    /* If the event has been sent already, the handles are now under the */
    /* responsibility of the debugger process, so we don't touch them    */
    if (!event->sent)
    {
        switch(event->code)
        {
        case CREATE_THREAD_DEBUG_EVENT:
            close_handle( debugger->process, event->data.create_thread.handle );
            break;
        case CREATE_PROCESS_DEBUG_EVENT:
            if (event->data.create_process.file != -1)
                close_handle( debugger->process, event->data.create_process.file );
            close_handle( debugger->process, event->data.create_process.thread );
            close_handle( debugger->process, event->data.create_process.process );
            break;
        case LOAD_DLL_DEBUG_EVENT:
            if (event->data.load_dll.handle != -1)
                close_handle( debugger->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( current, 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( debugger, 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( thread, 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;
    }
}
