#include "dbinterface.h"

DbInterface::DbInterface(){
    mysql_init(&mysql);
}

void DbInterface::set_nproc(int nproc){
    this->nproc = nproc;
}

void DbInterface::connect(char *host, char *username, char *password){
    mysql_connect(&mysql, host, username, password);
    mysql_select_db(&mysql,"faucets");
}

void DbInterface::close(){
    mysql_close(&mysql);
}

void DbInterface::insert_job(Job j){

    char query[1024];

    sprintf(query, "insert into jobInfo (name, type, minpe, maxpe, status, fd, argbuf, port) values(\"%s\", %d, %d, %d, %d, %d, \"%s\", %d)", j.name, j.type, j.min_proc, j.max_proc, j.status, j.client_soc_fd, j.argbuf, j.port);
    

    if(mysql_query(&mysql, query))
	printf("Error executing query\n");

    /*
    if(mysql_query(&mysql, query))
	return -1;
    
    sprintf(query, "select max(id) from jobInfo");
    if(mysql_query(&mysql, query))
	return -1;
    
    MYSQL_RES *res;
    MYSQL_ROW row;
    if (!(res = mysql_store_result(&mysql)))
	return -1;

    if (!(row = mysql_fetch_row(res)))
	return -1;
    
    int dbid = atoi(row[0]);
    mysql_free_result(res);
    return dbid;
    */
}

int DbInterface::get_max_port(){
    char query[1024];
    
    sprintf(query,"select max(port) from jobInfo where status=%d or status=%d",
	    RUNNING, QUEUED);

    if(mysql_query(&mysql, query))
	return -1;
    
    MYSQL_RES *res;
    MYSQL_ROW row;
    if (!(res = mysql_store_result(&mysql)))
	return -1;
    
    if (!(row = mysql_fetch_row(res)))
	return -1;

    int port = 0;
    if(row[0] != NULL)
	port = atoi(row[0]);
    mysql_free_result(res);
    return port;    
}

void DbInterface::update_status(int id, int status){
    char query[1024];
    sprintf(query, "update jobInfo set status=%d where id=%d", status, id);
    mysql_query(&mysql, query);
}

void DbInterface::update_bitmap(int id, char *bitmap){
    char query[1024];
    char sbitmap[256];
    int i;
    for(i = 0; i < nproc; i++)
	sbitmap[i] = bitmap[i] + '0';
    sbitmap[i] = 0;

    sprintf(query, "update jobInfo set bitmap='%s' where id=%d", sbitmap, id);
    mysql_query(&mysql, query);
}

void DbInterface::update_pid(int id, int pid){
    char query[1024];
    sprintf(query, "update jobInfo set pid=%d where id=%d", pid, id);
    mysql_query(&mysql, query);
}

Job * DbInterface::fetch_jobs(int status){
    char query[1024];
    sprintf(query, "select * from jobInfo where status=%d", status);

    printf("before query\n");
    if(mysql_query(&mysql, query))
	printf("error executing query\n");

    printf("after query\n");

    MYSQL_RES *res;
    MYSQL_ROW row;
    if (!(res = mysql_store_result(&mysql)))
	return NULL;

    int njobs = mysql_num_rows(res);
    if(njobs == 0)
	return NULL;

    Job *jobq = new Job(nproc);
    
    Job *cur_job = jobq;
    while((row = mysql_fetch_row(res))) {

	printf("in loop\n");
	cur_job->dbid = atoi(row[0]);
	strcpy(cur_job->name, row[1]);
	
	if(status >= RUNNING){
	    cur_job->pid = atoi(row[2]);
	    for(int i = 0; i < nproc; i++){
		cur_job->bit_map[i] = row[7][i] - '0';
		if(cur_job->bit_map[i])
		    cur_job->num_allocated_proc++;
	    }
	}

	cur_job->type = atoi(row[3]);
	cur_job->min_proc = atoi(row[4]);
	cur_job->max_proc = atoi(row[5]);
	
	cur_job->status = atoi(row[8]);	
	cur_job->client_soc_fd = atoi(row[9]);

	strcpy(cur_job->argbuf, row[10]);
	
	if(row[11] != NULL)
	    cur_job->port = atoi(row[11]);

	njobs --;
	if(njobs > 0)
	    cur_job->next = new Job(nproc);

	cur_job = cur_job->next;
    }

    mysql_free_result(res);
    return jobq;
}  

Job * DbInterface::fetch_running_jobs(){
    return fetch_jobs(RUNNING);
}

Job * DbInterface::fetch_queued_jobs(){
    return fetch_jobs(QUEUED);
}

void DbInterface::free_list(Job *jlist){
    Job *jptr = jlist;
    Job *prev = jptr;

    while(jptr != NULL){
	prev = jptr;
	jptr = jptr->next;
	delete prev;	
    }
}


