#include <arch/arch.h>
#include <parlib.h>
#include <rassert.h>
#include <stdlib.h>
#include <vcore.h>
#include <ros/mman.h>
#include <ros/resource.h>
#include <stdio.h>
#include <timing.h>
#include <uthread.h>

#define TEST_MMAP					 1
#define TEST_ONE_CORE				 2
#define TEST_ASK_FOR_TOO_MANY_CORES	 3
#define TEST_INCREMENTAL_CHANGES	 4
#define TEST_YIELD_OUT_OF_ORDER		 5
#define TEST_YIELD_0_OUT_OF_ORDER	 6
#define TEST_YIELD_ALL               7
#define TEST_SWITCH_TO_RUNNABLE_S	 8
#define TEST_CRAZY_YIELDS			 9
#define TEST_CONCURRENT_SYSCALLS	10

int test = TEST_SWITCH_TO_RUNNABLE_S;

static void global_tests(uint32_t vcoreid);

int main(int argc, char** argv)
{
	uint32_t vcoreid;
	int retval;
	vcore_init();

	if ((vcoreid = vcore_id())) {
		printf("Should never see me! (from vcore %d)\n", vcoreid);
	} else { // core 0
		printf("Hello from else vcore 0\n");
		printf("Multi-Goodbye, world, from PID: %d!\n", sys_getpid());
		switch (test) {
			case TEST_MMAP:
				printf("Testing MMAP\n");
				void *CT(8*PGSIZE) addr;
				addr = sys_mmap((void*SNT)USTACKTOP - 20*PGSIZE, 8*PGSIZE, 3,
				                MAP_FIXED | MAP_ANONYMOUS, -1, 0);
				printf("got addr = 0x%08x\n", addr);
				*(int*)addr = 0xdeadbeef;
				*(int*)(addr + 3*PGSIZE) = 0xcafebabe;
				// these should work
				printf("reading addr: 0x%08x\n", *(int*)addr);
				printf("reading addr+3pg: 0x%08x\n", *(int*)(addr + 3*PGSIZE));
				// this should fault
				printf("Should page fault and die now.\n");
				{ TRUSTEDBLOCK
				*(int*)(addr - 3*PGSIZE) = 0xdeadbeef;
				}
				printf("Should not see me!!!!!!!!!!!!!!!!!!\n");
				while(1);
			case TEST_ONE_CORE:
				retval = vcore_request(1);
				printf("One core test's core0's retval: %d\n", retval);
				printf("Check to see it's on a worker core.\n");
				while(1);
			case TEST_ASK_FOR_TOO_MANY_CORES:
				retval = vcore_request(12);
				printf("Asked for too many, retval: %d\n", retval);
				return 0;
			case TEST_INCREMENTAL_CHANGES:
				retval = vcore_request(4);
				break;
			default:
				retval = vcore_request(5);
		}
		if (retval)
			panic("failed to allocate cores!");
		printf("Should see me if you want to relocate core0's context "
		        "when moving from RUNNING_S\n");
	}

	// vcore0 only below here
	switch (test) {
		case TEST_YIELD_OUT_OF_ORDER:
			udelay(10000000);
			printf("Core 2 should have yielded, asking for another\n");
			retval = vcore_request(5);
			break;
		case TEST_YIELD_0_OUT_OF_ORDER:
			udelay(5000000);
			printf("Core %d yielding\n", vcoreid);
			sys_yield(0);
			printf("Core 0 came back where it left off in RUNNING_M!!!\n");
			break;
	}
	global_tests(vcoreid);
	printf("Vcore %d Done!\n", vcoreid);
	while (1);
	return 0;
}

void vcore_entry(void)
{
	uint32_t vcoreid;
	static int first_time = 1; // used by vcore2
	int retval;

	vcoreid = vcore_id();
	printf("Hello from vcore_entry in vcore %d\n", vcoreid);

	if ((vcoreid == 2) && first_time) {
		first_time = 0;
		switch (test) {
			case TEST_INCREMENTAL_CHANGES:
				// Testing asking for less than we already have
				udelay(1000000);
				printf("Asking for too few:\n");
				retval = vcore_request(2);
				printf("Should be -EINVAL(7): %d\n", retval);
				// Testing getting more while running
				printf("Asking for more while running:\n");
				udelay(1000000);
				retval = vcore_request(5);
				printf("core2's retval: %d\n", retval);
				break;
			case TEST_YIELD_OUT_OF_ORDER:
				printf("Core %d yielding\n", vcoreid);
				sys_yield(0);
				break;
			case TEST_YIELD_0_OUT_OF_ORDER:
				udelay(7500000);
				printf("Core 0 should have yielded, asking for another\n");
				retval = vcore_request(5);
		}
	}
	global_tests(vcoreid);
	printf("Vcore %d Done!\n", vcoreid);
}

static void global_tests(uint32_t vcoreid)
{
	int retval;
	switch (test) {
		case TEST_YIELD_ALL:
			printf("Core %d yielding\n", vcoreid);
			sys_yield(0);
			// should be RUNNABLE_M now, amt_wanted == 1
			while(1);
		case TEST_SWITCH_TO_RUNNABLE_S:
			if (vcoreid == 2) {
				printf("Core %d trying to request 0/ switch to _S\n", vcoreid);
				udelay(3000000);
				retval = vcore_request(0);
				// will only see this if we are scheduled()
				printf("Core %d back up! (retval:%d)\n", vcoreid, retval);
				printf("And exiting\n");
				exit(0);
			} 
			while(1);
		case TEST_CRAZY_YIELDS:
			udelay(300000*vcoreid);
			vcore_request(5);
			sys_yield(0);
			printf("should  never see me, unless you slip into *_S\n");
			break;
		case TEST_CONCURRENT_SYSCALLS:
			for (int i = 0; i < 10; i++) {
				for (int j = 0; j < 100; j++)
					sys_null();
				printf("Hello from vcore %d, iteration %d\n", vcoreid, i);
			}
			break;
	}
}
