#include "shared_course_info.h"


static SUBDIR_COURSE_LIST *
initialize_subdir_node(const char *subdir)
{
    SUBDIR_COURSE_LIST *ptr;
    ptr = (SUBDIR_COURSE_LIST *) malloc(sizeof(SUBDIR_COURSE_LIST));
    if(!ptr)
	cs_critical_error(ERR_MALLOC_FAILED, "initialize_subdir_node");
    strncpy(ptr->subdir, subdir, MAX_COURSE_SUBDIR +1);
    ptr->next = 0; 
    ptr->course_head =0;
    return ptr;
}

static COURSE_ID_SRC_LIST *
initialize_course_node(const char *dir_id, const char *subdir)
{
    COURSE_ID_SRC_LIST *ptr;
    CONFIG_STRUCT conf;
    char filename[MAX_PATH +1];

    ptr = (COURSE_ID_SRC_LIST *)malloc(sizeof(COURSE_ID_SRC_LIST));
    if(!ptr)
	cs_critical_error(ERR_MALLOC_FAILED, "initialize_course_node");
    strncpy(ptr->manhat_course_id, dir_id, MAX_COURSE_ID +1);
    if(*subdir == 'T')
	ptr->crs_type = TEMPLATE;
    else
    {
       snprintf(filename, MAX_PATH +1, "%s/%s", subdir, dir_id);
       read_configuration_file (filename, &conf);
       if(conf.standalone)
	ptr->crs_type = STANDALONE;
       else
	ptr->crs_type = CENTRAL;

    } 
    ptr->src_head =0;
    ptr->next =0;
   return ptr; 
}

static SRC_LIST *
initialize_src_node(const char *src_id)
{
    SRC_LIST *ptr;
    ptr = (SRC_LIST *)malloc(sizeof(SRC_LIST));
    if(!ptr)
	cs_critical_error(ERR_MALLOC_FAILED, "initialize_src_node");
    strncpy(ptr->src_id, src_id, MAX_COURSE_ID +1);
    ptr->next = 0; 
    return ptr;
}

static SRC_LIST *build_src_id(FILE *fp)
{
   SRC_LIST *ptr, *current =0, *head =0;
   char src_id[MAX_PATH +1];
   while(fgets(src_id, MAX_PATH +1,fp))
   {
	 src_id[strlen(src_id) -1] = '\0';
         ptr = initialize_src_node(src_id);
	 if(!head)
	      head = ptr;
	 else
	     current->next = ptr;
	 current = ptr;
   } 
   return head; 
}


static COURSE_ID_SRC_LIST *
build_course_src_id(const char *course_id, const char *subdir)
{
   COURSE_ID_SRC_LIST *one_course;
   char file_path[MAX_PATH +1];
   FILE *fp;



   one_course = initialize_course_node(course_id, subdir);

   snprintf(file_path, MAX_PATH + 1, "%s%s/%s/%s", COURSE_PATH, subdir, course_id, "org_id.txt");
   fp = fopen(file_path, "r");
   if(fp)
   {
      one_course->src_head = build_src_id(fp);
      fclose(fp);  
   } 
   else 
      one_course->src_head = initialize_src_node(one_course->manhat_course_id);
   return one_course;
}

static COURSE_ID_SRC_LIST *build_all_course_src(DIR *dir_p, const char *subdir)
{
   char full[MAX_PATH +1];
   struct dirent *dir_entry_p;
   COURSE_ID_SRC_LIST *ptr, *current =0, *head =0;

   snprintf(full, MAX_PATH +1, "%s%s", COURSE_PATH, subdir);
   while (NULL != (dir_entry_p = readdir (dir_p)))
   {
      if( (*(dir_entry_p->d_name)) != '.' )
      {
         if(isdirectory(full, dir_entry_p->d_name))
          {
              ptr = build_course_src_id(dir_entry_p->d_name, subdir);
	      if(!head)
                    head = ptr; 
	      else
	           current->next = ptr; 
              current = ptr;
	   }
      }
   }
   return head; 
}

static SUBDIR_COURSE_LIST *
build_one_subdir_list(const char *subdir)
{
   DIR *dir_p;
   char file_path[MAX_PATH +1];
   SUBDIR_COURSE_LIST *sub =0;
   COURSE_ID_SRC_LIST *temp = 0;


   snprintf(file_path, MAX_PATH + 1, "%s%s", COURSE_PATH, subdir);
   dir_p = opendir(file_path);
  if(dir_p)
    {

       temp = build_all_course_src(dir_p, subdir);
       if(temp)
       {
         sub = initialize_subdir_node(subdir);
         sub->course_head  = temp;
       }
    }
    closedir(dir_p);
   return sub;
}

int find_manhat_course_id(SUBDIR_COURSE_LIST *sub_list,  
		const char *sub_dir, const char *dir_id, char *manhat_course_id, COURSE_TYPE *crs_type)
{
   COURSE_ID_SRC_LIST *ptr;
   SUBDIR_COURSE_LIST *sub_ptr;
   SRC_LIST *src_ptr;
   for(sub_ptr = sub_list; sub_ptr; sub_ptr = sub_ptr->next)
   {
     if(!strcmp(sub_ptr->subdir, sub_dir))
     {
         for(ptr = sub_ptr->course_head; ptr; ptr = ptr->next)
         {
            for(src_ptr = ptr->src_head; src_ptr; src_ptr = src_ptr->next)
            {
	       if(!strcmp(src_ptr->src_id, dir_id))
	       {
		  strncpy(manhat_course_id, ptr->manhat_course_id, MAX_COURSE_ID +1);
		  *crs_type = ptr->crs_type;
		  return 1;
	       }
            }	       
        }
    }
   }
   return 0;
      
}

SUB_DIR_ID_NODE *
build_unique_subdir_list(XML_COURSE_INFO_LIST *list)    
{
    int found =0;
    SUB_DIR_ID_NODE *ptr, *current =0, *head =0;
    for(list->current = list->head; list->current; list->current = list->current->next)
    {
       found =0;
       if(!head)
       {
          ptr = (SUB_DIR_ID_NODE*) malloc(sizeof(SUB_DIR_ID_NODE));
	  if(!ptr)
	      cs_critical_error(ERR_MALLOC_FAILED, "build_unique_subdir_list");
	  strncpy(ptr->subdir_id,list->current->subdir, MAX_COURSE_SUBDIR +1); 
	  ptr->next =0; 
	  head = ptr;
	  current = head;
       }
       else
       {
	  current = head;
	   while(current)
	   {
	      if(!strcmp(current->subdir_id, list->current->subdir))
	      {
		  found = 1;
		  break;
	      }
	      current = current->next;
	   }
	   if(!found)
	   {
	       current = head;
	       while(current->next)
	       {
		  current = current->next;
	       }

               ptr = (SUB_DIR_ID_NODE*) malloc(sizeof(SUB_DIR_ID_NODE));
	       if(!ptr)
	          cs_critical_error(ERR_MALLOC_FAILED, "build_unique_subdir_list");
	      strncpy(ptr->subdir_id,list->current->subdir, MAX_COURSE_SUBDIR +1); 
	      ptr->next =0; 
	      current->next = ptr;

           }
       }
               
    }
    return head; 
}

SUBDIR_COURSE_LIST *
build_sub_list_info( SUB_DIR_ID_NODE *unique_dir_list)
{
    SUBDIR_COURSE_LIST *ptr =0, *current =0, *head =0;
    SUB_DIR_ID_NODE *s_ptr;
    for(s_ptr = unique_dir_list; s_ptr; s_ptr = s_ptr->next)
    {
	ptr = build_one_subdir_list(s_ptr->subdir_id);
	if(ptr)
	{
	  if(!head)
	    head = ptr;
	  else
	   current->next = ptr;
	  current = ptr;
	}
    }
    return head; 
}

void free_sub_list_info(SUB_DIR_ID_NODE *list)
{
    SUB_DIR_ID_NODE *ptr;
    while(list)
    {
        ptr = list->next;
	free(list);
	list = ptr;
    }
      
}

static void free_src_head(SRC_LIST *head)
{
      SRC_LIST *ptr;
      while(head)
      {
	  ptr = head->next;
	  free(head);
	  head = ptr;
      }
}

static void free_course_head(COURSE_ID_SRC_LIST *head)
{
       COURSE_ID_SRC_LIST *ptr;
       while(head)
       {
	    ptr = head->next;
	    if(head->src_head)
		  free_src_head(head->src_head);
	    free(head);
	    head = ptr;
       }
}

void free_subdir_course_list(SUBDIR_COURSE_LIST *list)
{
      SUBDIR_COURSE_LIST *ptr;
      while(list)
      {
	  ptr = list->next;
	  if(list->course_head)
		free_course_head(list->course_head);
	  free(list);
	  list = ptr;
      }
}



int 
list_courses(XML_COURSE_INFO_LIST *list, const char *key,  char *roster_path, SUBDIR_COURSE_LIST *sub_list)  
{
#define MAX_TMP_NAME 100 
   int i =0, j=0;
   char name[MAX_TMP_NAME];
   char manhat_course_id[MAX_COURSE_ID +1];
   int found = 0;
   COURSE_TYPE type;
   int count = 0;

   
   if(list->head)
   {

      cs_set_value("roster_path",  roster_path);
      for(list->current = list->head;  list->current; list->current = list->current->next)
      {
        found = find_manhat_course_id(sub_list,  
			list->current->subdir,list->current->dir_id,manhat_course_id, &type);
	if(found)
	{
           snprintf(name, MAX_TMP_NAME, "sis_course.%d.new", i);
	   cs_set_int_value(name, 0);
           snprintf(name, MAX_TMP_NAME, "sis_course.%d.type", i);
	   if(type == STANDALONE)
	      cs_set_int_value(name, 2);
	   else if(type == TEMPLATE)
	      cs_set_int_value(name, 1);
	   else
	      cs_set_int_value(name, 0);


	}
	else 
	{
           snprintf(name, MAX_TMP_NAME, "sis_course.%d.new", i);
	   cs_set_int_value(name, 1);
	   count++;
        }
	snprintf(name, MAX_TMP_NAME, "sis_course.%d.course_code", i);
	cs_set_value(name, list->current->course_code);
	snprintf(name, MAX_TMP_NAME, "sis_course.%d.course_title", i);
	cs_set_value(name, list->current->title);
	snprintf(name, MAX_TMP_NAME, "sis_course.%d.course_semester", i);
	cs_set_value(name, list->current->semester);
	snprintf(name, MAX_TMP_NAME, "sis_course.%d.subdir", i);
	cs_set_value(name, list->current->subdir);
	snprintf(name, MAX_TMP_NAME, "sis_course.%d.subdir_length", i);
	cs_set_int_value(name, strlen(list->current->subdir));
        snprintf(name, MAX_TMP_NAME, "sis_course.%d.org_id", i);
        cs_set_value(name, list->current->dir_id);

        snprintf(name, MAX_TMP_NAME, "sis_course.%d.id", i);
	if(found)
	   cs_set_value(name, manhat_course_id);
	else
	   cs_set_value(name, list->current->dir_id);

	snprintf(name, MAX_TMP_NAME, "sis_course.%d.id_length", i);
	if(found)
	   cs_set_int_value(name, strlen(manhat_course_id));
	else
	{
	   cs_set_int_value(name, strlen(list->current->dir_id));
           strncpy(list->current->instructor_title, "new", MAX_INSTRUCTOR + 1);
	}
        j =0;
	for(list->current->user_current=list->current->user_head;
		list->current->user_current; 
		list->current->user_current = list->current->user_current->next)
	{
	  if(list->current->user_current->data.group == FACULTY)
	  {
	    snprintf(name, MAX_TMP_NAME, "sis_course.%d.faculty.%d.fname", i, j);
	    cs_set_value(name, list->current->user_current->data.realname);
	    snprintf(name, MAX_TMP_NAME, "sis_course.%d.faculty.%d.lname", i, j);
	    cs_set_value(name, list->current->user_current->data.lastname);
	    j++; 
	  }
	}
        i++;
      }
   }
   else
     cs_critical_error(ERR_NO_DATA_FOUND, "");
  cs_set_int_value("total_courses", i);
  cs_set_int_value("new_course", count);
  cs_set_int_value("max_subdir", MAX_COURSE_SUBDIR);
  cs_set_int_value("max_id", MAX_COURSE_ID);
  return count;
#undef MAX_TMP_NAME 
}

