#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/neutrino.h>
#include <sys/procmgr.h>
#include <sys/dispatch.h>
#include <sys/sysmgr.h>
#include <sys/iofunc.h>
#include <fcntl.h>
#include <dlfcn.h>

const char* service_name = "/dev/test_ham";

int start_resmgr()
{
    resmgr_connect_funcs_t connect_funcs;
    resmgr_attr_t          resmgr_attr;
    resmgr_io_funcs_t      io_funcs;
    dispatch_t             *dpp;
    dispatch_context_t     *ctp;
    iofunc_attr_t          attr;
    iofunc_funcs_t         ocb_funcs = { _IOFUNC_NFUNCS, NULL, NULL };
    iofunc_mount_t         mount = { 0, 0, 0, 0, &ocb_funcs };

    if((dpp = dispatch_create()) == NULL) {
        printf("unable to allocate dispatch handle\n");
        return EXIT_FAILURE;
    }

    /* initialize resource manager attributes */
    memset(&resmgr_attr, 0, sizeof resmgr_attr);
    resmgr_attr.nparts_max = 1;
    resmgr_attr.msg_max_size = 2048;

    /* initialize functions for handling messages */
    iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
                     _RESMGR_IO_NFUNCS, &io_funcs);

    //connect_funcs.open = io_open;
    //io_funcs.write = io_write;
    //io_funcs.Acl = io_acl;

    /* initialize our device description structure */
    iofunc_attr_init (&attr, S_IFCHR | 0660, NULL, NULL);
    attr.mount = &mount;   // so we can alloc an OCB per open

    if(resmgr_attach(dpp, &resmgr_attr, service_name, _FTYPE_ANY, 0,
    	    &connect_funcs, &io_funcs, (RESMGR_HANDLE_T *)&attr) == -1) {
        printf("resmgr_attach failed\n");
        return EXIT_FAILURE;
    }

    /* allocate a context structure */
    ctp = dispatch_context_alloc(dpp);
    if(ctp == NULL)
    {
        printf("dispatch_context_alloc failed\n");
        return EXIT_FAILURE;
    }

    /* start the resource manager message loop */
    while(1) {
        if((ctp = dispatch_block(ctp)) == NULL) {
            printf("dispatch_block error\n");
            return EXIT_FAILURE;
        }
        dispatch_handler(ctp);
    }
}

int main (int argc, char *argv[])
{
    printf("process running...\n");

    procmgr_daemon(EOK, PROCMGR_DAEMON_KEEPUMASK);

    start_resmgr(); //random failed to restart

    //while(1); //always success

    // Code should never reach here
    printf("process exiting...\n");
    return 0;
}
