#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "hash.h"
#include "word.h"

#define MAX_BUFFER 150

unsigned int generate_hash(hash_table_t *ht, unsigned long int key) 
{
    /* Your code goes here */
}


hash_table_t* create_hash_table(unsigned int size, enum table_type type,
			unsigned long int (*getkey)(void *),
			int (*compare)(void *, void *))
{
    /* Your code goes here */
}


int insert(hash_table_t *ht, void *value, int *opcount)
{
    /* Your code goes here */
}


hash_node_t* search(hash_table_t *ht, void *value, int *opcount)
{
    /* Your code goes here */
}



int insert_chained(hash_table_t *ht, void *value, int *opcount)
{
    /* Your code goes here */
}

int insert_linear(hash_table_t *ht, void *value, int *opcount)
{
    /* Your code goes here */
    
}

int insert_quadratic(hash_table_t *ht, void *value, int *opcount)
{
   /* Your code goes here */
    
}

hash_node_t* search_chained(hash_table_t *ht, void *value, int *opcount)
{
    /* Your code goes here */
}


hash_node_t* search_linear(hash_table_t *ht, void *value, int *opcount)
{
    /* Your code goes here */
}



hash_node_t* search_quadratic(hash_table_t *ht, void *value, int *opcount)
{
    /* Your code goes here */
}



float insert_from_file(hash_table_t *ht, char * filename)
{
    FILE *fp;
    char buf[MAX_BUFFER] = "";
    int count=0, total=0;

    // attempt to open the file, then check whether that worked.
    if ((fp = fopen(filename, "r")) == NULL)
    {
    fprintf(stderr,"Could not open file %s\n",filename);
    return (1);
    }

    while (fgets(buf, sizeof(buf), fp) != NULL)
    {
	buf[strlen(buf)-1] = '\0';
        wordcount *wc = create_count(buf);
        total += printed_insert(ht, (void *)wc);
        count++;
    }

    fclose(fp);

    return (float) total/count;
}

float search_from_file(hash_table_t *ht, char * filename)
{
    FILE *fp;
    char buf[MAX_BUFFER] = "";
    int count=0, total=0;

    // attempt to open the file, then check whether that worked.
    if ((fp = fopen(filename, "r")) == NULL)
    {
    fprintf(stderr,"Could not open file %s\n",filename);
    return (1);
    }
    
    while (fgets(buf, sizeof(buf), fp) != NULL)
    {
	buf[strlen(buf)-1] = '\0';
        wordcount *wc = create_count(buf);
        total += printed_search(ht, (void *)wc);
        count++;
    }

    fclose(fp);

    return (float) total/count;
}


int printed_insert(hash_table_t* ht, void *value)
{
    int opcount = 0;
    insert(ht, value, &opcount);
    printf("Inserted (%lu,",ht->getkey(value));
    print_word(value);
    printf("), Opcount: %d\n", opcount);

    return opcount;
}

int printed_search(hash_table_t* ht, void *value)
{
    int opcount = 0;
    hash_node_t *search_node = search(ht, value, &opcount);
    printf("Searched valuel (%lu,",ht->getkey(value));
    print_word(value);
    printf("), Opcount: %d ", opcount);
    if(search_node)
        printf("Found\n");
    else
        printf(" Not Found\n");

    return opcount;
}

void print_hash_table_entries(hash_table_t *ht)
{
    int i;
    for(i=0; i< ht->size; i++)
    {
        hash_node_t *ptr = ht->head[i];
	// print the first one
	if (ptr != NULL)
        {
            printf("[%d]= (%lu,", i ,ptr->key);
	    print_word(ptr->value); // yes, breaking abstraction
            printf(") ");
            ptr=ptr->next;
        }
        else
            printf("[%d]= NULL ", i);

	// print the rest
        while(ptr!=NULL)
        {
            printf(" -> (%lu,", ptr->key);
	    print_word(ptr->value); // yes, breaking abstraction
            printf(") ");
            ptr=ptr->next;
        }
        printf("\n");
    }
}
