#include <stdlib.h>

#include <parlib/common.h>
#include <ros/syscall.h>
#include <ros/ring_syscall.h>
#include <ros/sysevent.h>
#include <parlib/arc.h>
#include <errno.h>
#include <parlib/arch/arch.h>
#include <sys/param.h>
#include <parlib/arch/atomic.h>
#include <parlib/vcore.h>

syscall_desc_pool_t syscall_desc_pool;
async_desc_pool_t async_desc_pool;
async_desc_t* current_async_desc;

struct arsc_channel global_ac;

void init_arc(struct arsc_channel* ac)
{
	// Set up the front ring for the general syscall ring
	// and the back ring for the general sysevent ring
	mcs_lock_init(&ac->aclock);
	ac->ring_page = (syscall_sring_t*)sys_init_arsc();

	FRONT_RING_INIT(&ac->sysfr, ac->ring_page, SYSCALLRINGSIZE);
	//BACK_RING_INIT(&syseventbackring, &(__procdata.syseventring), SYSEVENTRINGSIZE);
	//TODO: eventually rethink about desc pools, they are here but no longer necessary
	POOL_INIT(&syscall_desc_pool, MAX_SYSCALLS);
	POOL_INIT(&async_desc_pool, MAX_ASYNCCALLS);
}

// Wait on all syscalls within this async call.  TODO - timeout or something?
int waiton_group_call(async_desc_t* desc, async_rsp_t* rsp)
{
	syscall_rsp_t syscall_rsp;
	syscall_desc_t* d;
	int retval = 0;
	int err = 0;
	if (!desc) {
		errno = EINVAL;
		return -1;
	}

	while (!(TAILQ_EMPTY(&desc->syslist))) {
		d = TAILQ_FIRST(&desc->syslist);
		err = waiton_syscall(d);
		// TODO: processing the retval out of rsp here.  might be specific to
		// the async call.  do we want to accumulate?  return any negative
		// values?  depends what we want from the return value, so we might
		// have to pass in a function that is used to do the processing and
		// pass the answer back out in rsp.
		//rsp->retval += syscall_rsp.retval; // For example
		retval = MIN(retval, err);
		// remove from the list and free the syscall desc
		TAILQ_REMOVE(&desc->syslist, d, next);
		POOL_PUT(&syscall_desc_pool, d);
	}
	// run a cleanup function for this desc, if available
	if (desc->cleanup)
		desc->cleanup(desc->data);
	// free the asynccall desc
	POOL_PUT(&async_desc_pool, desc);
	return err;
}

// Finds a free async_desc_t, on which you can wait for a series of syscalls
async_desc_t* get_async_desc(void)
{
	async_desc_t* desc = POOL_GET(&async_desc_pool);
	if (desc) {
		// Clear out any data that was in the old desc
		memset(desc, 0, sizeof(*desc));
		TAILQ_INIT(&desc->syslist);
	}
	return desc;
}

// Finds a free sys_desc_t, on which you can wait for a specific syscall, and
// binds it to the group desc.
syscall_desc_t* get_sys_desc(async_desc_t* desc)
{
	syscall_desc_t* d = POOL_GET(&syscall_desc_pool);
	if (d) {
		// Clear out any data that was in the old desc
		memset(d, 0, sizeof(*d));
    	TAILQ_INSERT_TAIL(&desc->syslist, d, next);
	}
	return d;
}

// Gets an async and a sys desc, with the sys bound to async.  Also sets
// current_async_desc.  This is meant as an easy wrapper when there is only one
// syscall for an async call.
int get_all_desc(async_desc_t** a_desc, syscall_desc_t** s_desc)
{
	assert(a_desc && s_desc);
	if ((current_async_desc = get_async_desc()) == NULL){
		errno = EBUSY;
		return -1;
	}
	*a_desc = current_async_desc;
	if ((*s_desc = get_sys_desc(current_async_desc)))
		return 0;
	// in case we could get an async, but not a syscall desc, then clean up.
	POOL_PUT(&async_desc_pool, current_async_desc);
	current_async_desc = NULL;
	errno = EBUSY;
	return -1;
}

// This runs one syscall instead of a group. 

// TODO: right now there is one channel (remote), in the future, the caller
// may specify local which will cause it to give up the core to do the work.
// creation of additional remote channel also allows the caller to prioritize
// work, because the default policy for the kernel is to roundrobin between them.
int async_syscall(arsc_channel_t* chan, syscall_req_t* req, syscall_desc_t** desc_ptr2)
{
	// Note that this assumes one global frontring (TODO)
	// abort if there is no room for our request.  ring size is currently 64.
	// we could spin til it's free, but that could deadlock if this same thread
	// is supposed to consume the requests it is waiting on later.
	syscall_desc_t* desc = malloc(sizeof (syscall_desc_t));
	desc->channel = chan;
	syscall_front_ring_t *fr = &(desc->channel->sysfr);
	//TODO: can do it locklessly using CAS, but could change with local async calls
	struct mcs_lock_qnode local_qn = {0};
	mcs_lock_lock(&(chan->aclock), &local_qn);
	if (RING_FULL(fr)) {
		errno = EBUSY;
		return -1;
	}
	// req_prod_pvt comes in as the previously produced item.  need to
	// increment to the next available spot, which is the one we'll work on.
	// at some point, we need to listen for the responses.
	desc->idx = ++(fr->req_prod_pvt);
	syscall_req_t* r = RING_GET_REQUEST(fr, desc->idx);
	// CAS on the req->status perhaps
	req->status = REQ_alloc;

	memcpy(r, req, sizeof(syscall_req_t));
	r->status = REQ_ready;
	// push our updates to syscallfrontring.req_prod_pvt
	// note: it is ok to push without protection since it is atomic and kernel
	// won't process any requests until they are marked REQ_ready (also atomic)
	RING_PUSH_REQUESTS(fr);
	//cprintf("DEBUG: sring->req_prod: %d, sring->rsp_prod: %d\n", 
	mcs_lock_unlock(&desc->channel->aclock, &local_qn);
	*desc_ptr2 = desc;
	return 0;
}
// Default convinence wrapper before other method of posting calls are available

syscall_desc_t* arc_call(long int num, ...)
{
  	va_list vl;
  	va_start(vl,num);
	struct syscall *p_sysc = malloc(sizeof (struct syscall));
	syscall_desc_t* desc;
	if (p_sysc == NULL) {
		errno = ENOMEM;
		return 0;
	}
	p_sysc->num = num;
  	p_sysc->arg0 = va_arg(vl,long int);
  	p_sysc->arg1 = va_arg(vl,long int);
  	p_sysc->arg2 = va_arg(vl,long int);
  	p_sysc->arg3 = va_arg(vl,long int);
  	p_sysc->arg4 = va_arg(vl,long int);
  	p_sysc->arg5 = va_arg(vl,long int);
  	va_end(vl);
	syscall_req_t arc = {REQ_alloc,NULL, NULL, p_sysc};
	async_syscall(&SYS_CHANNEL, &arc, &desc);
	printf ( "%d pushed at %p \n", desc);
	return desc;
}

// consider a timeout too
// Wait until arsc returns, caller provides rsp buffer.
// eventually change this to return ret_val, set errno

// What if someone calls waiton the same desc several times?
int waiton_syscall(syscall_desc_t* desc)
{
	int retval = 0;
	if (desc == NULL || desc->channel == NULL){
		errno = EFAULT;
		return -1;
	}
	// Make sure we were given a desc with a non-NULL frontring.  This could
	// happen if someone forgot to check the error code on the paired syscall.
	syscall_front_ring_t *fr =  &desc->channel->sysfr;
	
	if (!fr){
		errno = EFAULT;
		return -1;
	}
	printf("waiting %d\n", vcore_id());
	syscall_rsp_t* rsp = RING_GET_RESPONSE(fr, desc->idx);

	// ignoring the ring push response from the kernel side now
	while (atomic_read(&rsp->sc->flags) != SC_DONE)
		cpu_relax();
	// memcpy(rsp, rsp_inring, sizeof(*rsp));
	
    // run a cleanup function for this desc, if available
    if (rsp->cleanup)
    	rsp->cleanup(rsp->data);
	if (RSP_ERRNO(rsp)){
		errno = RSP_ERRNO(rsp);
		retval = -1;
	} else 
		retval =  RSP_RESULT(rsp); 
	atomic_inc((atomic_t*) &(fr->rsp_cons));
	return retval;
}


