/***********************************************************/
/* general data structure for event handling & request     */
/* queuing                                                 */
/***********************************************************/
#include <req.h>
#include <stdlib.h>

//#include <nand.h>
//extern int maintid;
//extern int tids[NAND_CHIP_COUNT];
//static char mode[10] = "a+";
//
//extern uint32_t program[NAND_PAGE_COUNT];
//
//static FILE* open_file(char* fname){
//	return fopen(fname, mode);
//}
//
//static void close_file(FILE* file){
//	fclose(file);
//}
//
//#define FILENAME "req.c"
//#ifdef Debug
//#define LOG(fmt, ...){ \
//	int curr_tid = pthread_self(); \
//	char fname[20]; \
//	if(curr_tid == maintid){ \
//		strcpy(fname, "log_draft"); \
//	} \
//	else{ \
//		strcpy(fname, "log_chip0"); \
//		int i; \
//		for(i=0;i<NAND_CHIP_COUNT;i++){ \
//			if(tids[i] == curr_tid){ \
//				fname[8] = '0'+i; \
//			} \
//		} \
//	} \
//	FILE* file = open_file(fname); \
//	fprintf(file, "TRACE %s:%d. %s()(%d) - ", FILENAME, __LINE__, __func__, curr_tid); \
//	fprintf(file, fmt, ## __VA_ARGS__); \
//	fclose(file); \
//}
//#else
//#define LOG(fmt, ...)
//#endif

void reqFree(req_t* req) {
  free(req->specific);
  free(req);
}

void reqEnqueue(req_t* req, req_t** queue_p){
  req->next = *queue_p;
  if(req->next != 0) req->next->prev = req;
  req->prev = 0;
  *queue_p = req;
}

req_t* reqDequeue(req_t** queue_p){
  req_t* p = *queue_p;

  if(p==0){
  	return 0;
  }

  while(p->next != 0)
  	p = p->next;

//  LOG("p %x (prev %x next %x)\n", p, (p==0)?0:p->prev, (p==0)?0:p->next);
  if(p->prev != 0){
//  	req_t* prev = p->prev;
//  	prev->next = 0;
//  	LOG("prev %x prev->next %x\n", prev, prev->next);
  	p->prev->next = 0;
  	p->prev = 0;
  }
  else{
  	assert(p->next ==0);
  	*queue_p = 0;
  }

  p->next = 0;
  p->prev = 0;

  return p;
}

/**
 * pop specific req from queue
 *
 * @return 1 if popped, 0 otherwise
 */
bool_t
reqPop(req_t** queue_p, req_t* req){
	assert(req);

	req_t* p = *queue_p;

	if(p == req){
		*queue_p = req->next;
		if (*queue_p)
			(*queue_p)->prev = 0;
	}
	else{
		while(p != req){
			if(p==0){
				return 0;
			}
			p = p->next;
//			p = p->next;
//
//			if(p->next){
//				return 0;
//			}
		}

		/* definitely have prev, since this is not queue head*/
		p->prev->next = p->next;

		/*have next?*/
		if(p->next){
			p->next->prev = p->prev;
		}
	}

  p->prev = 0;
  p->next = 0;

  return 1;
}

void
req_activate(req_t* req, void* response){
	(req->handler)(req,response);
}

void
req_activate_caller(req_t* req, void* response){
	(req->caller_req->handler)(req->caller_req,response);
}
