#include <stdio.h>
#include <stdlib.h>
#include "waitq.h"

// return the waitq entry for the specified clientid, if it exists
waitq *waitq_peek(waitq *head,int clientid) {
  waitq *next = head;                        
                                             
  while (next) {                             
   if (next->clientid == clientid) {         
      return next;                           
    }                                        
    next = next->next;                       
  }                                          
  return 0;                                  
}                                            

// create a new waitq entry at the end of the list
waitq *new_waitq(waitq **head,int clientid,int num) {
  waitq *next = *head;                               
  waitq *q = malloc(sizeof(waitq));                  
  q->clientid = clientid;                            
  q->num_wanted = 1;                                 
  q->wlock = malloc(sizeof(int));                    
  q->wlock[0] = num;                                 
  q->next = 0;                                       
  if (!next) {                                       
    *head = q;                                       
  } else {                                           
    while (next->next) {                             
      next = next->next;                             
    }                                                
    next->next = q;                                  
  }                                                  
  return q;                                          
}                                                    

// add a sub-entry to the specified waitq entry
int addto_waitq(waitq *q,int num) {                        
  int i;
  for (i=0;i<q->num_wanted;i++) {
    if (q->wlock[i] == num) {
      return 0; // already added, nothing to do!
    }
  }
  q->num_wanted++;                                          
  q->wlock = realloc(q->wlock,sizeof(int) * q->num_wanted); 
  q->wlock[q->num_wanted-1] = num;
  return 1;
}                                                           

// remove a waitq from the lis
int remove_waitq(waitq **head,int clientid) {
  waitq *tmp;                                 
  waitq *next = *head;                        
                                              
  if (!next) return 0;                        
  if (next && next->clientid == clientid) {   
    *head = next->next;                       
    free(next->wlock);                        
    free(next);                               
    return 1;                                 
  }                                           
  while (next) {                              
    if (next->next && next->next->clientid) { 
      tmp = next->next;                       
      next->next = next->next->next;          
      free(tmp->wlock);                       
      free(tmp);                              
      return 1;                               
    }                                         
    next = next->next;                        
  }                                           
  return 0;                                   
}                                             

void dump_waitq(int n,waitq *q) {
  int i;

  printf("List[");
  while (q) {
    printf("List[");
    printf("%d,List[",q->clientid);
    for (i=0;i<q->num_wanted;i++) {
      printf("%d",q->wlock[i]);
      if (i+1 < q->num_wanted) printf(",");
    }
    printf("]");
    printf("]");
    q = q->next;
    if (q) printf(",");
  }
  printf("]");
}
