/*
 * 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,
               /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
                                                              THREAD_ALL_ACCESS, 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,
                                           /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
                                                                PROCESS_ALL_ACCESS, FALSE )) == -1)
        {
            if (handle != -1) close_handle( debugger->process, handle );
            return 0;
        }
        if ((event->data.create_process.thread = alloc_handle( debugger->process, thread,
               /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
                                                               THREAD_ALL_ACCESS, 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_INVALID_HANDLE );
        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 || thread->process != process || !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;
        /* copy the context into the reply */
        if (event->code == EXCEPTION_DEBUG_EVENT)
            memcpy( req + 1, &event->data, event_sizes[event->code] );
        send_reply( thread );
    }

    free_event( current, event );

    if (thread->exit_event)
    {
        /* we still have a queued exit event, promote it to normal event */
        thread->debug_event = thread->exit_event;
        thread->exit_event = NULL;
    }
    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)
    {
        /* exit events can happen while another one is still queued */
        assert( code == EXIT_THREAD_DEBUG_EVENT || code == EXIT_PROCESS_DEBUG_EVENT );
        thread->exit_event = event;
    }
    else thread->debug_event = event;

    link_event( debug_ctx, 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 */
    {
        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;
    return 1;
}

/* a thread is exiting */
void debug_exit_thread( struct thread *thread, int exit_code )
{
    struct thread *debugger = thread->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->process->running_threads == 1)
            /* this is the last thread, send an exit process event */
            queue_debug_event( debugger, thread, EXIT_PROCESS_DEBUG_EVENT, &event );
        else
            queue_debug_event( debugger, thread, EXIT_THREAD_DEBUG_EVENT, &event );
    }

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

        /* kill all debugged processes */
        kill_debugged_processes( thread, 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;
    }
}
