/*
 * Server-side pipe management
 *
 * Copyright (C) 1998 Alexandre Julliard
 * Copyright (C) 2001 Mike McCormack
 *
 * TODO:
 *   improve error handling
 */

#include "config.h"

#include <assert.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <unistd.h>

#include "winbase.h"

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

enum pipe_state
{
    ps_none,
    ps_idle_server,
    ps_wait_open,
    ps_wait_connect,
    ps_connected_server,
    ps_connected_client,
    ps_disconnected
};

struct named_pipe;

struct pipe_user
{
    struct object       obj;
    enum pipe_state     state;
    struct pipe_user   *other;
    struct named_pipe  *pipe;
    struct pipe_user   *next;
    struct pipe_user   *prev;
    struct thread      *thread;
    void               *func;
    void               *overlapped;
};

struct named_pipe
{
    struct object       obj;         /* object header */
    unsigned int        pipemode;
    unsigned int        maxinstances;
    unsigned int        outsize;
    unsigned int        insize;
    unsigned int        timeout;
    struct pipe_user   *users;
};

static void named_pipe_dump( struct object *obj, int verbose );
static void named_pipe_destroy( struct object *obj);

static const struct object_ops named_pipe_ops =
{
    sizeof(struct named_pipe),    /* size */
    named_pipe_dump,              /* dump */
    no_add_queue,                 /* add_queue */
    NULL,                         /* remove_queue */
    NULL,                         /* signaled */
    NULL,                         /* satisfied */
    NULL,                         /* get_poll_events */
    NULL,                         /* poll_event */
    no_get_fd,                    /* get_fd */
    no_flush,                     /* flush */
    no_get_file_info,             /* get_file_info */
    NULL,                         /* queue_async */
    named_pipe_destroy            /* destroy */
};

static void pipe_user_dump( struct object *obj, int verbose );
static void pipe_user_destroy( struct object *obj);
static int pipe_user_get_fd( struct object *obj );
static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );

static const struct object_ops pipe_user_ops =
{
    sizeof(struct pipe_user),     /* size */
    pipe_user_dump,               /* dump */
    default_poll_add_queue,       /* add_queue */
    default_poll_remove_queue,    /* remove_queue */
    default_poll_signaled,        /* signaled */
    no_satisfied,                 /* satisfied */
    NULL,                         /* get_poll_events */
    default_poll_event,           /* poll_event */
    pipe_user_get_fd,             /* get_fd */
    no_flush,                     /* flush */
    pipe_user_get_info,           /* get_file_info */
    NULL,                         /* queue_async */
    pipe_user_destroy             /* destroy */
};

static void named_pipe_dump( struct object *obj, int verbose )
{
    struct named_pipe *pipe = (struct named_pipe *)obj;
    assert( obj->ops == &named_pipe_ops );
    fprintf( stderr, "named pipe %p\n" ,pipe);
}

static void pipe_user_dump( struct object *obj, int verbose )
{
    struct pipe_user *user = (struct pipe_user *)obj;
    assert( obj->ops == &pipe_user_ops );
    fprintf( stderr, "named pipe user %p (state %d)\n", user, user->state );
}

static void named_pipe_destroy( struct object *obj)
{
    struct named_pipe *pipe = (struct named_pipe *)obj;
    assert( !pipe->users );
}

static void notify_waiter( struct pipe_user *user, unsigned int status)
{
    if(user->thread && user->func && user->overlapped)
    {
        /* queue a system APC, to notify a waiting thread */
        thread_queue_apc(user->thread,NULL,user->func,
            APC_ASYNC,1,2,user->overlapped,status);
    }
    if (user->thread) release_object(user->thread);
    user->thread = NULL;
    user->func = NULL;
    user->overlapped=NULL;
}

static void pipe_user_destroy( struct object *obj)
{
    struct pipe_user *user = (struct pipe_user *)obj;

    assert( obj->ops == &pipe_user_ops );

    if(user->overlapped)
        notify_waiter(user,STATUS_HANDLES_CLOSED);

    if(user->other)
    {
        close(user->other->obj.fd);
        user->other->obj.fd = -1;
        switch(user->other->state)
        {
        case ps_connected_server:
            user->other->state = ps_idle_server;
            break;
        case ps_connected_client:
            user->other->state = ps_disconnected;
            break;
        default:
            fprintf(stderr,"connected pipe has strange state %d!\n",
                            user->other->state);
        }
        user->other->other=NULL;
        user->other = NULL;
    }

    /* remove user from pipe's user list */
    if (user->next) user->next->prev = user->prev;
    if (user->prev) user->prev->next = user->next;
    else user->pipe->users = user->next;
    if (user->thread) release_object(user->thread);
    release_object(user->pipe);
}

static int pipe_user_get_fd( struct object *obj )
{
    struct pipe_user *user = (struct pipe_user *)obj;
    assert( obj->ops == &pipe_user_ops );
    return user->obj.fd;
}

static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
    if (reply)
    {
        reply->type        = FILE_TYPE_PIPE;
        reply->attr        = 0;
        reply->access_time = 0;
        reply->write_time  = 0;
        reply->size_high   = 0;
        reply->size_low    = 0;
        reply->links       = 0;
        reply->index_high  = 0;
        reply->index_low   = 0;
        reply->serial      = 0;
    }
    *flags = 0;
    return FD_TYPE_DEFAULT;
}

static struct named_pipe *create_named_pipe( const WCHAR *name, size_t len )
{
    struct named_pipe *pipe;

    if ((pipe = create_named_object( &named_pipe_ops, name, len )))
    {
        if (get_error() != STATUS_OBJECT_NAME_COLLISION)
        {
            /* initialize it if it didn't already exist */
            pipe->users = 0;
        }
    }
    return pipe;
}

static struct pipe_user *get_pipe_user_obj( struct process *process, handle_t handle,
                                            unsigned int access )
{
    return (struct pipe_user *)get_handle_obj( process, handle, access, &pipe_user_ops );
}

static struct pipe_user *create_pipe_user( struct named_pipe *pipe, int fd )
{
    struct pipe_user *user;

    user = alloc_object( &pipe_user_ops, fd );
    if(!user)
        return NULL;

    user->pipe = pipe;
    user->state = ps_none;
    user->other = NULL;
    user->thread = NULL;
    user->func = NULL;
    user->overlapped = NULL;

    /* add to list of pipe users */
    if ((user->next = pipe->users)) user->next->prev = user;
    user->prev = NULL;
    pipe->users = user;

    grab_object(pipe);

    return user;
}

static struct pipe_user *find_partner(struct named_pipe *pipe, enum pipe_state state)
{
    struct pipe_user *x;

    for(x = pipe->users; x; x=x->next)
    {
        if(x->state==state)
        break;
    }

    if(!x)
        return NULL;

    return (struct pipe_user *)grab_object( x );
}

DECL_HANDLER(create_named_pipe)
{
    struct named_pipe *pipe;
    struct pipe_user *user;

    reply->handle = 0;
    pipe = create_named_pipe( get_req_data(), get_req_data_size() );
    if(!pipe)
        return;

    if (get_error() != STATUS_OBJECT_NAME_COLLISION)
    {
        pipe->insize = req->insize;
        pipe->outsize = req->outsize;
        pipe->maxinstances = req->maxinstances;
        pipe->timeout = req->timeout;
        pipe->pipemode = req->pipemode;
    }

    user = create_pipe_user (pipe, -1);

    if(user)
    {
        user->state = ps_idle_server;
        reply->handle = alloc_handle( current->process, user, GENERIC_READ|GENERIC_WRITE, 0 );
        release_object( user );
    }

    release_object( pipe );
}

DECL_HANDLER(open_named_pipe)
{
    struct named_pipe *pipe;

    reply->handle = 0;
    pipe = create_named_pipe( get_req_data(), get_req_data_size() );
    if(!pipe)
        return;

    if (get_error() == STATUS_OBJECT_NAME_COLLISION)
    {
        struct pipe_user *partner;

        if ((partner = find_partner(pipe, ps_wait_open)))
        {
            int fds[2];

            if(!socketpair(PF_UNIX, SOCK_STREAM, 0, fds))
            {
                struct pipe_user *user;

                if( (user = create_pipe_user (pipe, fds[1])) )
                {
                    partner->obj.fd = fds[0];
                    notify_waiter(partner,STATUS_SUCCESS);
                    partner->state = ps_connected_server;
                    partner->other = user;
                    user->state = ps_connected_client;
                    user->other = partner;
                    reply->handle = alloc_handle( current->process, user, req->access, 0 );
                    release_object(user);
                }
                else
                {
                    close(fds[0]);
                }
            }
            release_object( partner );
        }
        else
        {
            set_error(STATUS_PIPE_NOT_AVAILABLE);
        }
    }
    else
    {
        set_error(STATUS_NO_SUCH_FILE);
    }

    release_object(pipe);
}

DECL_HANDLER(connect_named_pipe)
{
    struct pipe_user *user, *partner;

    user = get_pipe_user_obj(current->process, req->handle, 0);
    if(!user)
        return;

    if( user->state != ps_idle_server )
    {
        set_error(STATUS_PORT_ALREADY_SET);
    }
    else
    {
        user->state = ps_wait_open;
        user->thread = (struct thread *)grab_object(current);
        user->func = req->func;
        user->overlapped = req->overlapped;

        /* notify all waiters that a pipe just became available */
        while( (partner = find_partner(user->pipe,ps_wait_connect)) )
        {
            notify_waiter(partner,STATUS_SUCCESS);
            release_object(partner);
            release_object(partner);
        }
    }

    release_object(user);
}

DECL_HANDLER(wait_named_pipe)
{
    struct named_pipe *pipe;

    pipe = create_named_pipe( get_req_data(), get_req_data_size() );
    if( pipe )
    {
        /* only wait if the pipe already exists */
        if(get_error() == STATUS_OBJECT_NAME_COLLISION)
        {
            struct pipe_user *partner;

            set_error(STATUS_SUCCESS);
            if( (partner = find_partner(pipe,ps_wait_open)) )
            {
                /* this should use notify_waiter, 
                   but no pipe_user object exists now... */
                thread_queue_apc(current,NULL,req->func,
                    APC_ASYNC,1,2,req->overlapped,STATUS_SUCCESS);
                release_object(partner);
            }
            else
            {
                struct pipe_user *user;

                if( (user = create_pipe_user (pipe, -1)) )
                {
                    user->state = ps_wait_connect;
                    user->thread = (struct thread *)grab_object(current);
                    user->func = req->func;
                    user->overlapped = req->overlapped;
                    /* don't release it */
                }
            }
        }
        else
        {
            set_error(STATUS_PIPE_NOT_AVAILABLE);
        }
        release_object(pipe);
    }
}

DECL_HANDLER(disconnect_named_pipe)
{
    struct pipe_user *user;

    user = get_pipe_user_obj(current->process, req->handle, 0);
    if(!user)
        return;
    if( (user->state == ps_connected_server) &&
        (user->other->state == ps_connected_client) )
    {
        close(user->other->obj.fd);
        user->other->obj.fd = -1;
        user->other->state = ps_disconnected;
        user->other->other = NULL;

        close(user->obj.fd);
        user->obj.fd = -1;
        user->state = ps_idle_server;
        user->other = NULL;
    }
    release_object(user);
}

DECL_HANDLER(get_named_pipe_info)
{
    struct pipe_user *user;

    user = get_pipe_user_obj(current->process, req->handle, 0);
    if(!user)
        return;

    reply->flags        = user->pipe->pipemode;
    reply->maxinstances = user->pipe->maxinstances;
    reply->insize       = user->pipe->insize;
    reply->outsize      = user->pipe->outsize;

    release_object(user);
}

