/**********************************************************************
   FS_BLOCK.C
   Z-World, 2001
  
   This program will contact the DevMate and upload to it
   some files, that will be made available as a web page. The
   complimentary file, FS.C in the samples\dmunit directory
   should be used on the DevMate, to give this program something
   to talk to.
  
   As this program demonstrates all of the filesystem functions
   avaliable, it should not be run straight-through like normal.
   After the DevMate program is running, load this one on
   the target and insert a few breakpoints, where they are marked
   below. It can then be run to the breakpoints, and while it is
   stopped, different results can be seen on the web server.
  
   When comparing the different results on the web server, it is
   important to remember to do a full-refresh (shift-refresh in
   most browsers) such that the browser's internal cache is not
   relied upon. 
**********************************************************************/

/*
 * get some sample data to send
 */
#ximport "samples/tcpip/http/pages/static.html"    index_html
#ximport "samples/tcpip/http/pages/rabbit1.gif"    rabbit1_gif

/*
 * Define this to format the FS on the DevMate. This may not work
 * if another service, such as logging, has a file open on the DevMate!
 */
//#define FORMAT

/*
 * Turn on debug messages, if this is uncommented
 */
//#define TC_FS_DEBUG

/*
 * Select the filesystem support
 */
#define USE_TC_FS

/*
 * Uncomment this line if this program will be loaded over ethernet. This will
 * force the DevMate communication to use serial port A, re-using the programming
 * link that was used to download the program.
 */
//#define USE_TC_LOADER

#use "tc_conf.lib"

/*
 * the file pointer, that will be used in all commands to the SP
 */
DMFile file;

/*
 * Send a file to the DevMate, and
 * return it's file ID
 */
int send_file(long data, char *name)
{
	auto int retval;
	auto long big_len;
	auto int length, offset, writesize;
#define BUFSIZE	64
	auto char buf[BUFSIZE];
	auto FNumber id;

	/* find the length of the */
	if(xmem2root((char *)&big_len, data, 4)) {
		// error
		exit(1);
	}
	length = (int)big_len;
	offset = 0;
	
	printf("Opening file '%s'...\n",name);

	/* open the file */
	while(TC_PENDING == (retval = devmate_fs_open(&file, 0, name, TC_FS_FLAGS_NEWID)))
		devmate_tick();
	if(TC_SUCCESS != retval) {
		// error
		exit(2);
	}

	printf("Sending the file...\n");

	/* send the file */
	while(offset < length) {
		writesize = length - offset;
		if(writesize > BUFSIZE)
			writesize = BUFSIZE;

		/* get one block of data */
		if(xmem2root(buf, data + 4 + offset, writesize)) {
			// error
			exit(3);
		}

		/* send that block to the target */
		retval = devmate_fs_append(&file, buf, writesize);
		if(-1 == retval) {
			// error! transaction is cancled!
			exit(4);
		}
		offset += retval;

		/* drive the communications */
		devmate_tick();
	}

	printf("Send complete - closing the file...\n");

	/* file is written - close it all! */
	while(TC_PENDING == (retval = devmate_fs_close(&file,&id)))
		devmate_tick();

	if(TC_SUCCESS != retval) {
		// error
		exit(5);
	}

	printf("File '%s' sent correctly!\n",name);

	/* return the id of the created file */
	return id;
}

void main(void)
{
	int rv;
	long	timeout;
	FNumber index_file, logo_file, test_id;

	/*
	 * Standard initialization
	 */	
	devmate_init();

	/*
	 * Sync with the target
	 */
#ifdef FORMAT
	rv = devmate_fs_syncB(&file,TC_FS_FORMAT,0);
#else
	rv = devmate_fs_syncB(&file,0,0);
#endif
	if(TC_SUCCESS != rv) {
		printf("Error in init!\n");
		exit(-1);
	} else {
		printf("INIT was successfull!\n");
	}

	/*
	 * Send some data
	 */
	index_file = send_file(index_html,"/index.html");
	logo_file = send_file(rabbit1_gif,"/rabbit1.gif");

	/*********************************************
	 * ===---> INSERT A BREAKPOINT HERE! <---=== *
	 * Browse to "[ip_address]/index.html" to    *
	 * see the pages that were uploaded.         *
	 *********************************************/
	; // breakpoint handle

	/*
	 * Rename the index file
	 */
	rv = devmate_fs_idlookupB(&file,"/foo.html",&test_id,0);
	switch(rv) {
	case TC_ERROR:
		/* File does not exist */
		break;
	case TC_SUCCESS:
		break;
	}
	rv = devmate_fs_deleteB(&file,test_id,0);
	switch(rv) {
	case TC_ERROR:
		/* File not there anymore? */
		break;
	case TC_SUCCESS:
		break;
	}

	printf("Renaming '/index.html' to '/foo.html'... ");
	rv = devmate_fs_renameB(&file,index_file,"/foo.html",0);
	switch(rv) {
	case TC_ERROR:
		printf("Error!\n");
		exit(-1);
	case TC_SUCCESS:
		/* success! - do nothing */
		break;
	}
	printf("Done!\n");

	/*********************************************
	 * ===---> INSERT A BREAKPOINT HERE! <---=== *
	 * Browse to "[ip_address]/foo.html" to      *
	 * see the page as it is renamed.            *
	 *********************************************/
	; // breakpoint handle

	/*
	 * Verify the ID of the gif - it should match what we
	 * know it to be.
	 */
	printf("Looking up the file-ID of '/rabbit1.gif'... ");
	rv = devmate_fs_idlookupB(&file,"/rabbit1.gif",&test_id,0);
	switch(rv) {
	case TC_ERROR:
		printf("Error!\n");
		break;
	case TC_SUCCESS:
		break;
	}
	if(test_id == logo_file) {
		printf("Success!\n");
	} else {
		printf("Error in lookup!\n");
	}

	/*
	 * Delete the gif
	 */
	printf("Deleting '/rabbit1.gif'... ");
	rv = devmate_fs_deleteB(&file,logo_file,0);
	switch(rv) {
	case TC_ERROR:
		printf("Error!\n");
		exit(-1);
	case TC_SUCCESS:
		break;
	}
		
	/*********************************************************
	 * At this point the .gif file should be removed. Again, *
	 * browse to "[ip_address]/foo.html" (remember to reload *
	 * so the cache is not used!), and the picture on the    *
	 * page should be gone.                                  *
	 *********************************************************/

	printf("All done!\n");	
}