#include <tos.h>
#include <vdi.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "script.h"

static short echo_off = 1;

static void scripterror( char * msg )
{
	printf( "Error: %s\n", msg );
	printf("Press any key to continue\n");
	getch();
}

static int isspace( unsigned char x ) {
	
	int ret = 0;

	if( (x > 0 && x <= 0x20) || x == 255 ){
		ret = 1;
	}
	
	return( ret );
}

static char * strstrip( char * s ) 
{
	long size;
	char * end;
	
	size = strlen( s );
	if(!size){
		return( s );
	}
	
	end = s + size;
	while( end >= s && isspace(*end) ) 
		end--;
	if( end <= (s + size) )
		*end = '\0';
	
	while( *s && isspace(*s) ) 
		s++;
	return( s );
}

static char * getline( char ** curpos )
{
	char * start;
	char * end;
	static char line[SCRIPT_MAX_LEN+1];
	start = *curpos;
	
	if( *start == 0 ) {
		return( NULL );
	}
	
	end = strpbrk( start, "\r\n" );
	if( end == NULL ) {
		end = (start + strlen(start));
		if( end == start ) {
			return( NULL );
		}		
	}
	if( end < start ) {
		printf("getline: end < start!?\n");
		return( NULL );
	}

	if( (end-start) > 0 ){
		memcpy( line, start, end-start );
	}
	
	line[end-start]=0;
	*curpos += (end-start)+1;
	return( strstrip( line ) );
	
}

static long copy_file( char * src, char * dst)
{
	long count;
	int srcf,dstf;
	static buf[8192];
	
	srcf = Fopen( src, 0 );
	dstf = Fcreate( dst, 0 );
	
	if( srcf < 0 || dstf < 0 ){
		if( srcf > 0)
			Fclose( srcf );
		if( dstf > 0 )
			Fclose( srcf );
		return( -2 );
	}
	
	count = Fread( srcf, 8192, &buf );
	if( count > 0 ){
		do{
			Fwrite(dstf, count, &buf );
			count = Fread( srcf, 8192, &buf);
		}while( count > 0 );
	}
	
	Fclose(dstf);
	Fclose(srcf);	
		
	return( 0 );
}

static long exec_rewrite_cmd(char * line)
{
	long len_needle = -1;
	long len_repl = -1;
	FILE * fh;
	FILE * tmpfh;
	char * linebuf;
	char * linebuf2;
	char * needle;
	char * curchar;
	char * curchar2;
	char found = 0;

	char *arg1;
	char *arg2; 
	char *arg3; 
	
	arg1 = strstrip(line); 		/* filename 	*/
	if(arg1 == NULL) {
		scripterror("Invalid Arguments!\n");
		return(-1000);
	}
	
	arg2 = strchr(arg1, ' ');	/* needle   	*/
	if(arg2 == NULL) {
		scripterror("Invalid Arguments!\n");
		return(-1000);
	}
	
	arg3 = strchr(arg2+1, ' ');  /* replacement */
	if(arg3 == NULL) {
		scripterror("Invalid Arguments!\n");
		return(-1000);
	}
	
	*arg2 = 0;
	arg2++;	
	arg2 = strstrip( arg2 );	

	*arg3 = 0;
	arg3++;
	
	arg3 = strstrip( arg3 );
/*
	printf("Replacing line containing %s with %s in %s\n",
		arg2, arg3, arg1
	);
*/
	len_needle = strlen(arg2);
	len_repl = strlen(arg3);
	
	/* keep the original string: */
	needle = malloc(len_needle+1);
	
	strcpy(needle, arg2);	
	strlwr(needle);
	
	if( len_needle < 3 || len_repl < 3 ){
		scripterror("Invalid Argument lenght, each string must be at least 3 chracters long!\n");
		return(-1001);
	}
	
	/* read file, line by line */
 	/* foreach line */
 		/* when line contains needle */
 			/* write replacement */
 		/* else */
 			/* write orignal data */
 			
	fh = fopen(arg1, "rb");
   if(!fh){
     scripterror("Could not open input file!\n");
     return(-1002);
   }
   tmpfh = fopen("rewrite.tmp", "wb");
   if(!tmpfh){
   	scripterror("Could not open output temp. file!\n");
   	return(-1003);
   }
   
   linebuf = malloc(2048);
   linebuf2 = malloc(2048);
   while (feof(fh) == 0){
        fgets(linebuf, 2048, fh);
        strcpy(linebuf2, linebuf);
        strlwr(linebuf);
        if(strstr(linebuf, needle) != NULL){
        	curchar = linebuf;
        	curchar2 = linebuf2;
        	while(*curchar != 0){
        		if(strstr(curchar, needle) == curchar) {
        			fwrite(arg3, len_repl, 1, tmpfh);
        		 	curchar += len_needle;
        		 	curchar2 += len_needle;
        		} else {
        			fputc(*curchar2, tmpfh);
        			curchar++;
        			curchar2++;
        		}
        	}
        	found = 1;
        } else {
        	fwrite(linebuf2, strlen(linebuf), 1, tmpfh);
        }        
    }
   fclose(fh);
   fclose(tmpfh);
   
   if(found == 1) {
   	unlink(arg1);
   	copy_file("rewrite.tmp", arg1);
   }
   unlink("rewrite.tmp");
   
   free(needle);
   free(linebuf);
   free(linebuf2);
   #undef MAX_LINE_LEN
   return(0);
}

static long exec_copy_cmd( char * line )
{

	char * arg1 = strstrip(line);
	char * arg2 = strchr( arg1, ' ' );
	
	if( arg2 == NULL ){
		scripterror("Missing second parameter!\n");
		return(-1000);
	}	
	*arg2 = 0;
	arg2++;
	
	arg2 = strstrip( arg2 );
	
	if( strlen(arg1) > 2 && strlen(arg2) > 2 ){
		copy_file( arg1, arg2 );
	} else {
		scripterror("Parameters to copy must be at least 3 chartacters long!\n");
		return( -1001 );
	}
	
	return( 0 );
}

static long exec_set_cmd( char * line ){

	char * arg1 = strstrip(line);
	char * arg2 = strchr( arg1, ' ' );
	
	if( strlen(line) <= 1 || arg1 == NULL ) {
		scripterror("Missing first parameter!");
		return(-1000);
	}
	
	if( arg2 == NULL ){
		scripterror("Missing second parameter!");
		return(-1000);
	}	
	*arg2 = 0;
	arg2++;
	
	arg2 = strstrip( arg2 );
	
	if( strlen(arg1) >= 2 && strlen(arg2) >= 2 ){
		if( strncmp(arg1, "echo", 4) == 0 ) {
			if( strncmp(arg2, "on", 2) == 0 ){
				echo_off = 0;
			} 
			if( strncmp(arg2, "off", 3) == 0){
				echo_off = 1;
			}
			printf("echo is now %s\n", ( echo_off==1) ? "off" : "on" );
		}
	} else {
		scripterror("Invalid parameters passed to set!\n");
		return( -1001 );
	}
	
	return( 0 );
}

static long exec_pause_cmd( char * line ){

	char * arg1 = strstrip(line);
	if( strlen(arg1)<=1 ){
		printf("Press any key to continue...\n");
	} else {
		printf( "%s\n", arg1 );
	}
	getch();
	return( 0 );
}

static long exec_echo_cmd( char * line ){

	char * arg1 = strstrip(line);
	printf( "%s\n", arg1 );
	return( 0 );
}

static void parse_line( char * line ){

	long len;
	
	len = strlen( line ) ; 
	
	if( len < 1 ) {
		return;
	}
	if( strchr(line, '#') == line ){
		return;
	}
	
	if( echo_off == 0 )
		printf("%s\n", line );	
	
	if( strncmp( line, "copy", 4) == 0 ) {
		exec_copy_cmd( line+4 );
	}
	else if( strncmp( line, "pause", 5) == 0 ) {
		exec_pause_cmd( line+5 );
	}
	else if( strncmp( line, "echo", 4) == 0 ) {
		exec_echo_cmd( line+4 );
	}
	else if( strncmp( line, "set", 3) == 0 ) {
		exec_set_cmd( line+3 );
	}
	else if( strncmp( line, "rewrite", 7) == 0 ) {
		exec_rewrite_cmd( line+7 );
	}
}

static char script_copy[SCRIPT_MAX_LEN+1];
long execute_script( char * script_in )
{
	char ** curline;
	char * line; 
	
	*curline=&script_copy[0];
	
	strncpy( script_copy, script_in, SCRIPT_MAX_LEN );
	script_copy[SCRIPT_MAX_LEN]=0;

	while( strlen(*curline) > 0 && (line=getline(curline)) != NULL ) {
		if( strlen(line) > 0 ) { 
			parse_line( line );
		}
	}
	return( 0 );
}