#include <stdio.h>
#include <cubeos.h>
#include <tpu.h>
#include <tpud.h>
#include <qsm.h>
//#include <sai_cube.h>
#include <rdio.h>
#include <ptimer.h>
#include <ttyio.h>

#include "readcmd.h"
#include "testmak.h"

/* tests */
#define MAXTESTS 16

int EmptyTest ();		// tests the test facility, defined below

int TimerTest ();		// tests the timer irq and the daytime clock
//#include "rcjtest.h"
#include "i2ctest.h"
#include "camtest.h"
#include "i2ccam.h"

/* table of tests */
struct test {
	int (*entry) ();
	int interactive;
	char *name;
	int success;
	int failure;
};
struct test tests[MAXTESTS];
int testnr;
void newtest (int (*test_entry) (), int interactive, char *name);


/* add your tests here */
void init_tests ()
{
	newtest (EmptyTest, 0, "Empty test");
	newtest (TimerTest, 0, "Timer test");
	newtest (I2CTest, 0, "I2C Test");
//	newtest (RCJTest,1,"RCJ test");
//	newtest (RCJTest2,1,"RCJ2 test");
	newtest (CamTest,1,"CamTest");
	newtest (CamI2CTest,1,"CamI2CTest");
	newtest (ViewTest,1,"ViewTest");
	newtest (PictureTest,1,"PictureTest");
	newtest (JPEGTest,1,"JPEGTest");
	newtest (JPEGGTest,1,"JPEG Grayscale Test");
	newtest (RAWTest,1,"RAWTest");
	newtest (JPEGFake,1,"JPEGFake");
	newtest (CAM_setyuv,1,"Set YUV");
	newtest (CAM_setycrcb,1,"Set YCrCb");

}

/* don't change anything down here */

void newtest (int (*test_entry) (), int interactive, char *name)
{
	if (testnr == 0) {
		int i;
		printf ("Cleaning up tests...");
		for (i = 0; i < MAXTESTS; i++) {
			tests[i].entry = NULL;
			tests[i].name = NULL;
			tests[i].success = 0;
			tests[i].failure = 0;
		}
		printf ("done\n");
	}
	if (testnr < MAXTESTS) {
		tests[testnr].entry = test_entry;
		tests[testnr].interactive = interactive;
		tests[testnr].name = name;
		testnr++;
	}
}

void dotest (int i)
{
	int ret;
	if (tests[i].entry == NULL) {
		printf ("no such test %d\n", i);
		return;
	}
	printf ("\nRunning test %d:", i);
	if (tests[i].name) {
		printf ("%s\n", tests[i].name);
	} else {
		printf ("\n");
	}
	fflush (stdout);

	ret = tests[i].entry ();

	fflush (stdout);
	printf ("\n");

	if (ret) {
		printf ("test %d FAILED:%d ", i, ret);
		if (tests[i].name) {
			printf ("%s\n", tests[i].name);
		} else {
			printf ("\n");
		}
	} else {
		printf ("test %d SUCCEDED ", i);
		if (tests[i].name) {
			printf ("%s\n", tests[i].name);
		} else {
			printf ("\n");
		}
	}

}


int EmptyTest ()
{
	printf ("Empty Test\n");
	return 0;
}

int TimerTest ()
{
	int i;
	unsigned long oldtime;
	int success;

	success = 0;
	printf ("watching clockticks");
	fflush (stdout);
	oldtime = _gettimeofday ();

	for (i = 0; i < 1000000; i++) {
		if (oldtime != _gettimeofday ()) {
			oldtime = _gettimeofday ();
			printf (".");
			fflush (stdout);
			success++;
		}
	}

	printf ("seen %d ticks", success);
	failif (success == 0, "Clock is not ticking");
	return (0);

}


int main (int argc, char *argv[])
{
	int i, j;
	int quit = 0;
	unsigned long *adr;
	char test[256];
	char c;
	char *command;

//	TTY_setcontty(2);

	RCJ_init();

	testnr = 0;

	TTY_outchar('C');
	TTY_outchar('\n');
	TTY_outchar('\r');


	printf ("\nCubeOS Testsuite V1.0\n");
	TTY_Blocking_Serial_Out=0;

	TTY_outchar('U');
	TTY_outchar('\n');
	TTY_outchar('\r');

	printf ("NL/CR test:\nERROR\rOK   \n");
	TTY_outchar('B');
	TTY_outchar('\n');
	TTY_outchar('\r');

	TTY_outchar('E');
	TTY_outchar('\n');
	TTY_outchar('\r');


	printf ("please press another key to continue>");
	TTY_outchar('\n');
	TTY_outchar('\r');


	I2C_init_camera();



	fflush (stdout);
	c = TTY_inchar();
	printf ("\nGot %c: %d\n", c, c);
	init_LED ();

	init_tests ();


	do {
		printf ("\n\navailable tests:\n");
		for (i = 0; i < testnr; i++) {
			printf ("%2d:%c ", i, (tests[i].interactive ? 'I' : ' '));
			if (tests[i].name) {
				printf ("%s\n", tests[i].name);
			} else {
				printf ("\n");
			}
		}

		command = readcmd ("test(#/q/a)?");

		if (!strcmp (command, "q")) {
			quit = 1;
		} else {
			if (!strcmp (command, "a")) {
				printf ("\n\nRunning all noninteractive tests\n");
				LED_ON ();
				for (i = 0; i < testnr; i++)
					if (!tests[i].interactive)
						dotest (i);
				LED_OFF ();
			} else {

				j = sscanf (command, "%d", &i);

				if ((j == 1) && (i >= 0) && (i < testnr)) {
					LED_ON ();
					dotest (i);
					LED_OFF ();
				} else {
					printf ("no such test \n");
				}
			}

		}

	} while (!quit);


	return (0);
}

