/******************************************************************************
 * Copyright (c) 2004, 2007 IBM Corporation
 * All rights reserved.
 * This program and the accompanying materials
 * are made available under the terms of the BSD License
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/bsd-license.php
 *
 * Contributors:
 *     IBM Corporation - initial implementation
 *****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#include <cfgparse.h>

int glob_come_from_cr = 0;

int find_next_entry(int file, struct ffs_chain_t *chain)
{
#define MAX_LINE_SIZE 1024
	char lnbuf[MAX_LINE_SIZE], b0=0, b1=0;
	char *start, *end, *next;
	struct ffs_header_t *hdr; //, *hdr2;
	int lc, rc;
	char c;
	
	/* search for new config line */
	if (0 == glob_come_from_cr) {
		while (1 == (rc = read(file, &c, 1))) {
			//printf("b0=%c b1=%c c=%c\n",
			//		b0, b1, c);
			b0 = b1;
			b1 = c;
			/* this looks for starting sign "<CR>[^#]" */
			if (  ((0x0a == b0)  || (0x0d == b0)) &&
			      (('#'   != b1) && (0x0a != b1)  && 
			       (0x0d != b1))) {
				break;
			}
		}
	} else {
		/* normalize */
		while (1 == (rc = read(file, &c, 1))) {
			//printf("read c=%c\n", c);
			if ((0x0a != c) && (0x0d != c)) {
				break;
			}
		}
		glob_come_from_cr = 0;
		//printf("debug: glob_come_from_cr = 0\n");
	}
	if (1 != rc) {
		return 1;
	}

	/* now buffer it until end of line */
	memset((void*) lnbuf, 0, MAX_LINE_SIZE);
	lnbuf[0] = c;
	lc = 1;
	while ((1 == read(file, &(lnbuf[lc]), 1)) && (lc < MAX_LINE_SIZE)) {
		//printf("read lnbuf=%c\n", lnbuf[lc]);
		if ((0x0a == lnbuf[lc]) || (0x0d == lnbuf[lc])) {
			glob_come_from_cr = 1;
			//printf("debug: glob_come_from_cr = 1\n");
			break;
		}
		lc++;
	}

	/* allocate header */
	hdr = malloc(sizeof(struct ffs_header_t));
	if (NULL == hdr) {
		perror("alloc memory");
		return 2;
	}
	memset((void*)hdr, 0, sizeof(struct ffs_header_t));

	/* attach header to chain */
	if (0 != add_header(chain, hdr)) {
		return 2;
	}

	/**********************************************************/
	/* extract token name *********************************** */
	start = NULL;
	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
		printf("parsing error 1");
		return 2;
	}
	/* get memory for it */
	hdr->token = malloc(end - start + 1);
	if (NULL == hdr->token) {
		return 2;
	}
	/* set string */
	strncpy(hdr->token, start, end - start + 1);
	hdr->token[end - start] = 0;

	/**********************************************************/
	/* extract file name *********************************** */
	if (NULL == next) {
		return 2;
	}
	start = next;
	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
		printf("parsing error 1");
		return 2;
	}

	/* get memory for it */
	hdr->imagefile = malloc(end - start + 1);
	if (NULL == hdr->imagefile) {
		return 2;
	}

	/* check if file is existing */

	/* set string */
	strncpy(hdr->imagefile, start, end - start + 1);
	hdr->imagefile[end - start] = 0;

	/* check if entry is linked to another header */
	if (':' == *start) {
		printf("\nERROR: links are removed as feature in this version\n");
		return 2;

		/*
		start++;
		if (0 != find_entry_by_token(chain, hdr->imagefile+1, &hdr2)) {
			printf("[%s]: link to [%s] not found\n", 
					hdr->token, hdr->imagefile+1);
			dump_fs_contents(chain);
			return 2;
		}
		hdr->linked_to = hdr2;
		*/
	}

	/**********************************************************/
	/* extract flags name *********************************** */
	if (NULL == next) {
		return 2;
	}
	start = next;
	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
		printf("parsing error 1");
		return 2;
	}
	hdr->flags = strtoul(start, NULL, 16);

	/**********************************************************/
	/* extract rom start name *********************************** */
	if (NULL == next) {
		return 2;
	}
	start = next;
	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
		printf("parsing error 1");
		return 2;
	}
	if ('-' == *start) {
		/* this means not specific address request for data */
		hdr->romaddr = 0;
	} else {
		/* data has to begin at specific address */
		hdr->romaddr = strtoul(start, NULL, 16);
	}

	return 0;
}

void debug_print_range(char *s, char *e)
{
	while (s < e) {
		printf("%c", *s);
		s++;
	}
}

int inbetween_white(char *s, int max, char **start, char **end, char **next)
{
	int pos = 0, posalt;

	if (NULL != *start) {
		pos = *start - s;
		s   = *start;
	}

	/* wind to first non white */
	while (pos < max) {
		if ((' ' == *s) || ('	' == *s)) {
			s++;
			pos++;
			continue;
		}
		break;
	}
	if (pos >= max) {
		/* no non-white found */
		return 1;
	}

	/* assign start */
	*start = s;

	/* wind to end of non white or end of buffer */
	posalt = pos;
	while (pos < max) {
		if ((' '  == *s) || ('	' == *s) || 
		    (0x0a == *s) || (0x0d == *s)) {
			break;
		}
		s++;
		pos++;
	}

	if (pos == posalt) {
		return 1;
	}

	*end = s;

	if ((pos + 1) >= max) {
		*next = NULL;
	} else {
		*next = s;
	}

	return 0;
}

int add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr)
{
	struct ffs_header_t *next;

	if (NULL == chain->first) {
		chain->first = hdr;
		return 0;
	}
	next = chain->first;

	/* find last */
	while (NULL != next->next) {
		next = next->next;
	}
	next->next = hdr;

	return 0;
}

int find_entry_by_token(struct ffs_chain_t *chain, char *token,
			struct ffs_header_t **hdr)
{
	struct ffs_header_t *next;

	if (NULL == chain->first) {
		*hdr = NULL;
		return 1;
	}
	next = chain->first;

	//printf("debug: search for [%s]...\n", token);

	while (1) {
		//printf("       > [%s]\n", next->token);
		if (strcmp(token, next->token) == 0) {
			*hdr = next;
			//printf("       > found\n");
			break;
		}
		if (NULL == next->next) {
			//printf("       > reached end of chain, not found\n");
			return 1;
		}
		next = next->next;
	}
	return 0;
}

void dump_fs_contents(struct ffs_chain_t *chain)
{
	struct ffs_header_t *next;

	if (NULL == chain->first) {
		printf("no contents in fs\n");
		return;
	}
	next = chain->first;

	while (1) {
		if (NULL != next->token) {
			printf("Token [%s] ", next->token);
		} else {
			printf(" [not-set], ");
		}

		if (NULL != next->imagefile) {
			printf(" <%s>, ", next->imagefile);
		} else {
			printf(" file<not-set>, ");
		}

		printf("flags<%llx>, ", next->flags);
		printf("romaddr<%llx>, ", next->romaddr);
		
		if (NULL != next->linked_to) {
			printf("linked to [%s]", next->linked_to->token);
		}
		
		printf("\n");
		if (NULL == next->next) {
			break;
		}

		next = next->next;
	}
			
}

void free_chain_memory(struct ffs_chain_t *chain)
{
	struct ffs_header_t *hdr, *next_hdr;

	if (NULL != chain->first) {
		hdr = chain->first;
		chain->first = NULL;
	} else {
		return;
	}

	while (NULL != hdr) {
		//printf("%p  ", hdr);
		if (NULL != hdr->token) {
			//printf("free up %s\n", hdr->token);
			free(hdr->token);
		}
		if (NULL != hdr->imagefile) {
			free(hdr->imagefile);
		}
		next_hdr = hdr->next;
		free(hdr);
		hdr = next_hdr;
	}
}


/*
 * Detect duplicate entries in the romfs list
 */
void find_duplicates(struct ffs_chain_t *chain)
{
	struct ffs_header_t *act, *sub;

	if (NULL == chain->first) {
		printf("no contents in fs\n");
		return;
	}
	act = chain->first;

	do {
		sub = act->next;
		while (sub != NULL) {
		
			if (act->token == NULL || sub->token == NULL) {
				printf("find_duplicates: token not set!\n");
			}
			else if (strcmp(act->token, sub->token) == 0) {
				printf("*** NOTE: duplicate romfs file '%s'.\n", act->token);
			}
			sub = sub->next;
		}

		act = act->next;

	} while (act != NULL);
	
}
