#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>

#define MAXSTRINGLEN 1024

#include "configure.h"

#define streq(a,b) (!(strcmp((a), (b))))

int logtype = LOG_COMMON;

char *configfile = 0;
char servername[MAXSTRINGLEN];
char logfile[MAXSTRINGLEN];
char filepath[MAXSTRINGLEN];
char webpath[MAXSTRINGLEN];
int domainAliasesTotal = 0;
char *domainNameDefault = 0;
char *domainAliases[DOMAIN_ALIASES_MAX];
int domainMakeChart = 0;
int has_prefix = 0;
int has_suffix = 0;
char prefix[MAXSTRINGLEN];
char suffix[MAXSTRINGLEN];
char *ignored_sites[SITES_MAX];
int ignored_sites_t = 0;

char *items[ITEMS_MAX];
int item_accs[ITEMS_MAX];
int items_t = 0;

char *hidden_items[ITEMS_MAX];
int hidden_items_t = 0;
char *ignored_items[ITEMS_MAX];
int ignored_items_t = 0;

void remove_trailing_sp(/* char *s */);

void stringtolower(/* char *s */);

void configure() {
	if (!configfile) {
		fprintf(stderr, "Error: -c option not specified.\n");
		fprintf(stderr, "-c must be used to specify a configuration file.\n");
		usage();
		exit(-1);
	} else {
		FILE *in;
		char s[MAXSTRINGLEN];
		in = fopen(configfile, "r");
		if (!in) {
			fprintf(stderr, "Error: configuration file %s not found.\n", configfile);
			exit(-1);
		}
		if (!getline(in, s)) {
			fprintf(stderr, "Error in configuration file: empty?\n");
			exit(-1);
		}
		if (streq(s, "CERN_HTTPD")) {
			logtype = LOG_CERN_OLD;
		} else if (streq(s, "NCSA_HTTPD")) {
			logtype = LOG_NCSA_OLD;
		} else if (streq(s, "COMMON")) {
			logtype = LOG_COMMON;
		} else if (streq(s, "PLEXUS_HTTPD")) {
			logtype = LOG_PLEXUS;
		} else {
			fprintf(stderr, "Error in configuration file: server type line missing or invalid.\n");
		} 
		getline(in, servername);
		getline(in, prefix);
		if (streq(prefix, "none")) {
			has_prefix = 0;
		} else {
			has_prefix = 1;
		}
		getline(in, suffix);
		if (streq(suffix, "none")) {
			has_suffix = 0;
		} else {
			has_suffix = 1;
		}
		getline(in, filepath);
		getline(in, webpath);
		getline(in, logfile);
		if (!getline(in, s)) {
			fprintf(stderr, 
				"Your configuration file is too short.\n");
			fprintf(stderr, 
				"Please read the documentation and add the new information required.\n");
			exit(1);
		}
		if (streq(s, "{")) {
			fprintf(stderr, 
				"You are missing the default domain line.\n");
			fprintf(stderr, 
				"Please read the documentation and add the new information required.\n");
			exit(1);
		}
		domainNameDefault = mystrdup(s);
		if ((!getline(in, s)) || (!streq(s, "{"))) {
			fprintf(stderr, 
				"{ expected at start of hidden items.\n");
			fprintf(stderr,
				"Please update your configuration file\n");
			fprintf(stderr,
				"and add the information required\n");
			fprintf(stderr,
				"(see the documentation).\n");
			exit(-1);
		}
		while(1) {
			if (!getline(in, s)) {
				fprintf(stderr,
					"unexpected end of file\n");
				exit(-1);
			}
			if (streq(s, "}")) {
				break;
			}
			remove_trailing_sp(s);
			hidden_items[hidden_items_t++] = mystrdup(s);
		}	
		if (!getline(in, s)) {
			/* No more stanzas- we can tolerate that */
			return;
		}
		if (!streq(s, "{")) {
			fprintf(stderr, 
				"{ expected at start of ignored items\n");
			exit(-1);
		}
		while(1) {
			if (!getline(in, s)) {
				fprintf(stderr,
					"unexpected end of file\n");
				exit(-1);
			}
			if (streq(s, "}")) {
				break;
			}
			remove_trailing_sp(s);
			ignored_items[ignored_items_t++] = mystrdup(s);
		}	
		if (!getline(in, s)) {
			/* No more stanzas- we can tolerate that */
			return;
		}
		if (!streq(s, "{")) {
			fprintf(stderr, 
				"{ expected at start of ignored sites\n");
			exit(-1);
		}
		while(1) {
			if (!getline(in, s)) {
				fprintf(stderr,
					"unexpected end of file\n");
				exit(-1);
			}
			if (streq(s, "}")) {
				break;
			}
			remove_trailing_sp(s);
			ignored_sites[ignored_sites_t++] = mystrdup(s);
		}	
		if (!getline(in, s)) {
			/* No more stanzas- we can tolerate that */
			return;
		}
		if (streq(s, "none")) {
			/* No domain charts desired -- that's OK */
			return;
		}
		domainMakeChart = 1;
		domainAliasesTotal = 0;
		if (!streq(s, "{")) {
			fprintf(stderr, 
				"{ expected at start of domain aliases\n");
				exit(-1);
		}
		while(1) {
			if (!getline(in, s)) {
				/* No more stanzas- we can tolerate that */
				return;
			}
			if (streq(s, "}")) {
				break;
			} else if (!streq(s, "{")) {
				fprintf(stderr,
			"{ expected at the start of each domain alias.\n");
				exit(-1);
			} else {
				char *alias;
				if (!getline(in, s)) {
					fprintf(stderr,
		"Unexpected end of file in domain alias\n");
					exit(-1);
				}
				/* 2048 really ought to be enough at
					4 chars/country = a 512-country
					continent (we'll realloc this down) */
				domainAliases[domainAliasesTotal] = (char*)
					malloc(sizeof(char) * 2048);
				alias = domainAliases[domainAliasesTotal];
				strcpy(alias, " ");
				strcat(alias, s);
				strcat(alias, " ");
				while (1) {
					if (!getline(in, s)) {
						fprintf(stderr,
			"Unexpected end of file in domain alias\n");
						exit(-1);
					}
					if (streq(s, "}")) {
						int len;
						len = strlen(alias);
						domainAliases
						[domainAliasesTotal] =
						(char*)realloc(alias,
						sizeof(char) * (len + 1));
						domainAliasesTotal++;
						break;
					}
					stringtolower(s);
					strcat(alias, s);
					strcat(alias, " ");
				}
			}
		}		
	}
}

int getline(in, s)
	FILE *in; 
	char *s; 
{
	while(!feof(in)) {
		int i, sc, len;
		if (!fgets(s, 80, in)) {
			return 0;
		}
		if (s[0] == '#') {
			continue;
		}
		if (s[strlen(s)-1] == '\n') {
			s[strlen(s)-1] = '\0';
		}
		len = strlen(s);
		sc = 0;
		/* Whitespace stomper */
		for (i=0; (i<len); i++) {
			if (isspace(s[i])) {
				sc++;
			} else {
				break;
			}
		}
		if (sc) {
			char buf[81];
			strcpy(buf, s + sc);				
			strcpy(s, buf);
		}
		/* Trailing (lot easier) */
		len = strlen(s);
		for (i=(len-1); i>=0; i--) {
			if (isspace(s[i])) {
				s[i] = '\0';
			} else {
				break;
			}
		}
		return 1;
	}
	return 0;
}	

void remove_trailing_sp(s)
	char *s; 
{
	int i;
	while(1) {
		int l;
		l = strlen(s);
		if (!l) {
			return;
		}
		if (s[l-1] == ' ') {
			s[l-1] = '\0';
		} else {
			return;
		}
	}
}

void stringtolower(s)
	char *s; 
{
	int i;
	int len;
	len = strlen(s);
	for (i=0; (i<len); i++) {
		if (isalpha(s[i])) {
			if (isupper(s[i])) {
				s[i] = tolower(s[i]);
			}
		}
	}
}

char *mystrdup(s)
	char *s;
{
	char *n;
	n = (char *)malloc((strlen(s) + 1) * sizeof(char));
	strcpy(n, s);
	return n;
}
