#include "mkserv.h"

/* Test program fro mkserv */
char *progname;

void 
usage()
{
	printf("%s: [test numbers]\n", progname);
	printf("Test 1: walk_tree test\n");
	return;
}

main(int argc, char **argv) 
{
	int test;

	progname = argv[0];
	if(argc == 1) {
		usage();
		exit(1);
	}
	argv++;

	while (--argc != 0) {
		test=atoi(argv[0]);
		if(!test) {
			usage();
			exit(1);
		}
		switch (test) {
		case 1:
		case 2:
			test_walk_tree(test);
			/* Directory tree tests */
			break;
		case 3:
			test_fix_root_links(test);
			break;
		case 4:
			test_find_in_string(test);
			break;
		case 5:
			test_vno(test);
			break;
		case 6:
			test_read_file_header(test);
			break;
		case 7:
			test_get_service(test);
			break;
		case 8:
			test_set_environment(test);
			break;
		case 9:
			test_parse_cmd(test);
			break;
		default:
			usage();
			exit(1);
		}
		argv++;
	}
	exit(0);
}



test_walk_tree_print(char *name, struct stat *sbuf, char *opt, char *opt2)
{
	if((strcmp(opt, "TEST1234") && strcmp(opt, "TEST2"))
	   || strcmp(opt2,"T3")) {
		printf("Fail opt test for %s\n", name);
		return 1;
	}
	if(!strcmp(opt, "TEST2")) 
		if((sbuf->st_mode & S_IFMT) != S_IFLNK) return 0;
	printf("%s\n", name);
	return 0;
}

test_walk_tree(int test)
{	
	switch(test) {
	case 1:
		walk_tree("/", test_walk_tree_print, "TEST1234", "T3");
		break;
	case 2:
		walk_tree("/", test_walk_tree_print, "TEST2", "T3");
		break;
	default:
		printf("Bad test in test_walk_tree\n");
	}
}

/* ARGSUSED */
test_fix_root_links(int test)
{	
	fix_root_links("/var/server", "/srvd");
}

/* ARGSUSED */
test_find_in_string_1(char *s, char *s1, int off) 
{
	char *ret;
	ret = find_in_string(s, s1);
	if(ret == NULL) ret = s1-1;
	if(ret-s1 == off) {
		/* printf("  Passed test :%s:%s:%d\n", s, s1, off); */
		return 0;
	}
	else {
		printf("  Botched test :%s:%s:%d:%d\n", s, s1, off, ret-s1);
		return 1;
	}
}

/* ARGSUSED */
test_find_in_string(int test)
{
	int t=0;
	printf("--------------\nTesting find_in_string\n");
#define T(a,b,c) t += test_find_in_string_1(a,b,c)
	T("/mit", "/mit/epeisach/src", 0);
	T("/mit", "a/mit/epeisach/src", 1);
	T("/mit", "/mit", 0);
	T("/mit", "mit/fmit/mfit", -1);
	T("/mit", "mit+2/mit",5);
	printf("Next test fails\n");
	/* Fail test */
	T("/mit", "mit+2/mit",1);
#undef T
	if(t != 1) printf("Tests failed......\n");
	else printf("Tests passed\n");
	printf("-------------\n");
}

cmp_version_test(char *a, char * b, int c)
{
	int r;
	r = cmp_version(a, b);
	if( r != c) {
		printf("Botched test %s %s %d %d\n", a, b, c, r);
		return 1;
	}
	return 0;
}

/* ARGSUSED */
test_vno(int test)
{
	int t=0;
	printf("--------------\nTesting vno\n");
#define T(a,b,c) t += cmp_version_test(a,b,c)
	T(NULL, NULL, 0);
	T(NULL, "1", 1);
	T(NULL, "1.", 1);
	T("1", NULL, -1);
	T("1.1", NULL, -1);
	T("1", "1", 0);
	T("1.1", "1", -1);
	T("1.1", "1.1.1", 1);
	T("2.1", "1", -1);
	T("1.1", "1.2", 1);
	T("1.1", "1.2.1", 1);
#undef T
	if(t != 0) printf("Tests failed......\n");
	else printf("Tests passed\n");
	printf("-------------\n");
}

/* ARGSUSED */
test_read_file_header(int test)
{
	struct file_header fh;
	int t=0;

	bzero(&fh, sizeof(struct file_header));

	printf("--------------\nTesting file_headers\n");
	if(!get_file_header("tests/non_existant_file", &fh)) {
		printf("Failed test on nonexistant file\n");
	}

	if(get_file_header("tests/foo.c", &fh)) {
		printf("Failed test on foo.c\n");	
		t++;
	}
	if(strcmp(fh.version, "1.1")) {
		printf("Failed test on foo.c :%s:\n", fh.version);
		t++;
	}

	/* Tests for empty version line */
	if(get_file_header("tests/foo1.c", &fh)) {
		printf("Failed test on foo.c\n");	
		t++;
	}
	if(fh.version) {
		printf("Failed test on foo1.c :%s:\n", fh.version);
		t++;
	}

	if(get_file_header("tests/foo2.c", &fh)) {
		printf("Failed test on foo.c\n");	
		t++;
	}
	if(fh.version) {
		printf("Failed test on foo2.c :%s:\n", fh.version);
		t++;
	}

	if(t != 0) printf("Tests failed......\n");
	else printf("Tests passed\n");
	printf("-------------\n");
}

/* ARGSUSED */
test_get_service(int test)
{
	struct service serv;

	int t=0;
	struct search_path *path= NULL;

	bzero(&serv, sizeof(struct service));

	(void) mkdir("/tmp/test_mkserv", 0777);

	printf("--------------\nTesting service\n");

	t += append_service_path(&path, "./test_scripts");
	t += append_service_path(&path, "./non_existant_directory");
	t += append_service_path(&path, "/tmp/test_mkserv");
	print_service_path(path);


	serv.name = "none";

	if(get_service(&serv, path) != ENOENT) {
		printf("Failed test on nonexistant file\n");
		t++;
	}

	serv.name = "foo";
	if(get_service(&serv, path)) {
		printf("Failed test on foo service\n");
		t++;
	}
	/* Check results */
	if(((serv.exists[S_ADD] + serv.exists[S_DEL] + serv.exists[S_SYNC]) *
	   (1 - serv.exists[S_DEP])) != 3) {
		printf("Failed consistancy test on foo\n");
		t++;
	}

	if(cmp_version(serv.fh[S_ADD].version, "1.1")) {
		printf("Add version wrong %s\n", serv.fh[S_ADD]);
		t++;
	}
	if(cmp_version(serv.fh[S_DEL].version, "1.1.2")) {
		printf("Del version wrong %s\n", serv.fh[S_DEL]);
		t++;
	}
	if(cmp_version(serv.fh[S_SYNC].version, "2.1")) {
		printf("Sync version wrong %s\n", serv.fh[S_SYNC]);
		t++;
	}


	if(t != 0) printf("Tests failed......\n");
	else printf("Tests passed\n");
	printf("-------------\n");
}

/* ARGSUSED */
test_set_environment(int test)
{
	struct local_env env;
	if(setup_env(&env)) {
		printf("Could not setup environment test\n");
	}
	system("printenv");
}

/* ARGSUSED */
test_parse_cmd(int test)
{
	int t=0;
	struct cmd_line c;
	char *argv[10];

	printf("Testing cmd parsing\n");
        {
		int argc = 1;
		argv[0]="mkserv";

		/* Usage is wrong... */
		if(parse_cmd(argc, argv, &c) != -1) {
			printf("Failed test 1\n");
			t++;
		}
		if(strcmp(c.progname, "mkserv")) {
			printf("Test 1, name wrong\n");
			t++;
		}
		if(c.vflag+c.update+c.clean+c.public != 0) {
			printf("Test 1, vars wrong\n");
			t++;
		}
		if(c.services) {
			printf("Test 1, services wrong\n");
			t++;
		}
		   
	}
        {
		int argc = 2;
		argv[0]="mkserv";
		argv[1]="foo";

		/* Usage is wrong... */
		if(parse_cmd(argc, argv, &c) != 0) {
			printf("Failed test 2\n");
			t++;
		}
		if(strcmp(c.progname, "mkserv")) {
			printf("Test 1, name wrong\n");
			t++;
		}
		if(c.vflag+c.update+c.clean+c.public != 0) {
			printf("Test 2, vars wrong\n");
			t++;
		}
		if(!(c.services && c.services->del==0 && !strcmp(c.services->sname,"foo") && c.services->next == NULL)) {
			printf("Test 2, services wrong\n");
			t++;
		}		   
	}
        {
		int argc = 4;
		argv[0]="mkserv";
		argv[1]="foo";
		argv[2] = "-v";
		argv[3] = "-bar";

		if(parse_cmd(argc, argv, &c) != 0) {
			printf("Failed test 3\n");
			t++;
		}
		if(strcmp(c.progname, "mkserv")) {
			printf("Test 3, name wrong\n");
			t++;
		}
		if((1-c.vflag)+c.update+c.clean+c.public != 0) {
			printf("Test 3, vars wrong\n");
			t++;
		}
		if(!(c.services && c.services->del==0 && !strcmp(c.services->sname,"foo") && c.services->next && c.services->next->del == 1 && c.services->next->next ==NULL && !strcmp(c.services->next->sname, "bar"))) {
			t++;
		}
	}		   
        {
		int argc = 6;
		argv[0]="mkserv";
		argv[1]="foo";
		argv[2] = "-v";
		argv[3] = "-bar";
		argv[4] = "-foo";
		argv[5] = "-bar";

		if(parse_cmd(argc, argv, &c) != 0) {
			printf("Failed test 3\n");
			t++;
		}
		if(strcmp(c.progname, "mkserv")) {
			printf("Test 4, name wrong\n");
			t++;
		}
		if((1-c.vflag)+c.update+c.clean+c.public != 0) {
			printf("Test 4, vars wrong\n");
			t++;
		}
		if(!(c.services && c.services->del==1 && !strcmp(c.services->sname,"bar") && c.services->next == NULL)) {
			printf("Test 4, services wrong\n");
			t++;
		}
	}		   
	if(t) printf("Tests FAILED\n");
	else printf("Tests passed\n");
	printf("-------------------------------\n");

	
}

