// File: CMU-SAFARI[P]optimal-seed-solver/testSpacedSeedSolver.cc
// Function: main
int main(int argc, const char* argv[]) {
	int frequency;
	map <int, unsigned long long> frequencyCounter;

	SpacedSeedSolver solver;

	if (argc != 3 && argc != 4) {
		cerr << "USAGE: ./testOptimalSolver <Ref File> <TableFile> <Mask>" << endl;
		cerr << "USAGE: ./testOptimalSolver <TableFile> <Read File>" << endl;
		exit(1);
	}

	if (argc == 4) {
		solver.generateHash(argv[1], argv[3]);
		solver.storeHash(argv[2]);
			
		return 0;
	}

	cout << "Loading tree " << argv[1] << " into memory.\n";
	solver.loadHash(argv[1]);
	cout << "Finished loading. \n";

	int seedNum;
	//cout << "Please input number of seeds: ";
	cin >> seedNum;

	//int seedLength;

	ifstream readFile;
	readFile.open(argv[2]);
	string read;
	
	char benchFileName[80];
	strcpy(benchFileName, argv[2]);
	char* benchName = strtok(benchFileName, ".");
	
	ofstream output;
	output.open( (string(benchName) + string(".space") ).c_str() );

	while (seedNum > 0) {	
		//cout << "Please input seed length: ";
		//cin >> seedLength;
		
		frequencyCounter.clear();

		//Start reading the file
		readFile.clear();
		readFile.seekg(0, ios::beg);

		//Name
		getline(readFile, read);
		//Read
		getline(readFile, read);
		//cout << "DNA: " << read << endl;

		//Solve
		frequency = solver.solveDNA(read, seedNum);
		if (frequencyCounter.find(frequency) == frequencyCounter.end() )
			frequencyCounter[frequency] = 1;
		else
			frequencyCounter[frequency]++;

		//Trash
		getline(readFile, read);
		getline(readFile, read);
			
		//Name
		getline(readFile, read);

		while (!readFile.eof()) {
			//Read
			getline(readFile, read);
			//cout << "DNA: " << read << endl;

			//Solve
			if (read.find('N') == string::npos) {
				frequency = solver.solveDNA(read, seedNum);
				if (frequencyCounter.find(frequency) == frequencyCounter.end() )
					frequencyCounter[frequency] = 1;
				else
					frequencyCounter[frequency]++;
			}

			//Trash
			getline(readFile, read);
			getline(readFile, read);
			
			//Name
			getline(readFile, read);
		}

		cout << "seedNum: " << seedNum << endl;
		output << "seedNum: " << seedNum << endl;
		for (map<int, unsigned long long>::iterator iter = frequencyCounter.begin(); iter != frequencyCounter.end(); iter++)
			output << iter->first << ": " << iter->second << endl;

		cin >> seedNum;
	}
	
	return 0;
}

// Assembly:
subq $0xa28, %rsp            # imm = 0xA28
movl $0x0, 0xa24(%rsp)
movl %edi, 0xa20(%rsp)
movq %rsi, 0xa18(%rsp)
leaq 0x9e0(%rsp), %rdi
callq 0x4590
leaq 0x718(%rsp), %rdi
callq 0x6090
jmp 0x38dd
cmpl $0x3, 0xa20(%rsp)
je 0x399b
cmpl $0x4, 0xa20(%rsp)
je 0x399b
movq 0x196f0(%rip), %rdi     # 0x1cff0
leaq 0x116fd(%rip), %rsi     # 0x15004
callq 0x32c0
movq %rax, 0xf8(%rsp)
jmp 0x3916
movq 0xf8(%rsp), %rdi
movq 0x19693(%rip), %rsi     # 0x1cfb8
callq 0x3310
jmp 0x392c
movq 0x196bd(%rip), %rdi     # 0x1cff0
leaq 0x11703(%rip), %rsi     # 0x1503d
callq 0x32c0
movq %rax, 0xf0(%rsp)
jmp 0x3949
movq 0xf0(%rsp), %rdi
movq 0x19660(%rip), %rsi     # 0x1cfb8
callq 0x3310
jmp 0x395f
movl $0x1, %edi
callq 0x33a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x456a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x455d
cmpl $0x4, 0xa20(%rsp)
jne 0x3be2
movq 0xa18(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xe0(%rsp)
leaq 0x6e7(%rsp), %rdi
movq %rdi, 0xe8(%rsp)
callq 0x35d0
movq 0xe0(%rsp), %rsi
movq 0xe8(%rsp), %rdx
leaq 0x6e8(%rsp), %rdi
callq 0x45a0
jmp 0x39f1
movq 0xa18(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0xd0(%rsp)
leaq 0x6bf(%rsp), %rdi
movq %rdi, 0xd8(%rsp)
callq 0x35d0
movq 0xd0(%rsp), %rsi
movq 0xd8(%rsp), %rdx
leaq 0x6c0(%rsp), %rdi
callq 0x45a0
jmp 0x3a39
leaq 0x718(%rsp), %rdi
leaq 0x6e8(%rsp), %rsi
leaq 0x6c0(%rsp), %rdx
callq 0x6190
jmp 0x3a58
leaq 0x6c0(%rsp), %rdi
callq 0x31d0
leaq 0x6bf(%rsp), %rdi
callq 0x3330
leaq 0x6e8(%rsp), %rdi
callq 0x31d0
leaq 0x6e7(%rsp), %rdi
callq 0x3330
movq 0xa18(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0xc0(%rsp)
leaq 0x697(%rsp), %rdi
movq %rdi, 0xc8(%rsp)
callq 0x35d0
movq 0xc0(%rsp), %rsi
movq 0xc8(%rsp), %rdx
leaq 0x698(%rsp), %rdi
callq 0x45a0
jmp 0x3ad4
leaq 0x718(%rsp), %rdi
leaq 0x698(%rsp), %rsi
callq 0x6680
jmp 0x3aeb
leaq 0x698(%rsp), %rdi
callq 0x31d0
leaq 0x697(%rsp), %rdi
callq 0x3330
movl $0x0, 0xa24(%rsp)
movl $0x1, 0x690(%rsp)
jmp 0x4534
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x3b87
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x3b6d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
leaq 0x6c0(%rsp), %rdi
callq 0x31d0
leaq 0x6bf(%rsp), %rdi
callq 0x3330
leaq 0x6e8(%rsp), %rdi
callq 0x31d0
leaq 0x6e7(%rsp), %rdi
callq 0x3330
jmp 0x455d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x3bd0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
leaq 0x698(%rsp), %rdi
callq 0x31d0
leaq 0x697(%rsp), %rdi
callq 0x3330
jmp 0x455d
movq 0x193df(%rip), %rdi     # 0x1cfc8
leaq 0x11480(%rip), %rsi     # 0x15070
callq 0x32c0
movq %rax, 0xb8(%rsp)
jmp 0x3bff
movq 0xb8(%rsp), %rdi
movq 0xa18(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0x32c0
movq %rax, 0xb0(%rsp)
jmp 0x3c22
movq 0xb0(%rsp), %rdi
leaq 0x1144d(%rip), %rsi     # 0x1507e
callq 0x32c0
jmp 0x3c38
movq 0xa18(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xa0(%rsp)
leaq 0x66f(%rsp), %rdi
movq %rdi, 0xa8(%rsp)
callq 0x35d0
movq 0xa0(%rsp), %rsi
movq 0xa8(%rsp), %rdx
leaq 0x670(%rsp), %rdi
callq 0x45a0
jmp 0x3c80
leaq 0x718(%rsp), %rdi
leaq 0x670(%rsp), %rsi
callq 0x67d0
jmp 0x3c97
leaq 0x670(%rsp), %rdi
callq 0x31d0
leaq 0x66f(%rsp), %rdi
callq 0x3330
movq 0x19310(%rip), %rdi     # 0x1cfc8
leaq 0x113ce(%rip), %rsi     # 0x1508d
callq 0x32c0
jmp 0x3cc6
movq 0x1930b(%rip), %rdi     # 0x1cfd8
leaq 0x668(%rsp), %rsi
callq 0x31c0
jmp 0x3cdc
leaq 0x460(%rsp), %rdi
callq 0x3370
jmp 0x3ceb
movq 0xa18(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0x460(%rsp), %rdi
movl $0x8, %edx
callq 0x31e0
jmp 0x3d0b
leaq 0x440(%rsp), %rdi
callq 0x3480
movq 0xa18(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0x3f0(%rsp), %rdi
movq %rdi, 0x98(%rsp)
callq 0x32b0
movq 0x98(%rsp), %rdi
leaq 0x117e5(%rip), %rsi     # 0x1552d
callq 0x34f0
movq %rax, 0x3e8(%rsp)
leaq 0x1e8(%rsp), %rdi
callq 0x3570
jmp 0x3d64
movq 0x3e8(%rsp), %rax
movq %rax, 0x88(%rsp)
leaq 0x1a7(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x35d0
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
leaq 0x1a8(%rsp), %rdi
callq 0x45a0
jmp 0x3da8
leaq 0x17f(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0x35d0
movq 0x80(%rsp), %rdx
leaq 0x112d5(%rip), %rsi     # 0x150a1
leaq 0x180(%rsp), %rdi
callq 0x45a0
jmp 0x3ddb
leaq 0x1c8(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
leaq 0x180(%rsp), %rdx
callq 0x4660
jmp 0x3dfa
leaq 0x1c8(%rsp), %rdi
callq 0x3150
movq %rax, %rsi
leaq 0x1e8(%rsp), %rdi
movl $0x10, %edx
callq 0x3060
jmp 0x3e1e
leaq 0x1c8(%rsp), %rdi
callq 0x31d0
leaq 0x180(%rsp), %rdi
callq 0x31d0
leaq 0x17f(%rsp), %rdi
callq 0x3330
leaq 0x1a8(%rsp), %rdi
callq 0x31d0
leaq 0x1a7(%rsp), %rdi
callq 0x3330
cmpl $0x0, 0x668(%rsp)
jle 0x44cc
leaq 0x9e0(%rsp), %rdi
callq 0x4750
movq 0x460(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x460(%rsp,%rax), %rdi
xorl %esi, %esi
callq 0x3550
jmp 0x3e97
xorl %edx, %edx
movl %edx, %esi
leaq 0x460(%rsp), %rdi
callq 0x3470
jmp 0x3eaa
leaq 0x460(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x30c0
jmp 0x3ec1
leaq 0x460(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x30c0
jmp 0x3ed8
leaq 0x158(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x3160
jmp 0x3eef
movl 0x668(%rsp), %edx
leaq 0x718(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x6a20
movl %eax, 0x7c(%rsp)
jmp 0x3f11
movl 0x7c(%rsp), %eax
movl %eax, 0xa14(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x31d0
leaq 0x9e0(%rsp), %rdi
leaq 0xa14(%rsp), %rsi
callq 0x4780
movq %rax, 0x70(%rsp)
jmp 0x3f45
movq 0x70(%rsp), %rax
movq %rax, 0x150(%rsp)
leaq 0x9e0(%rsp), %rdi
callq 0x47b0
movq %rax, 0x148(%rsp)
leaq 0x150(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x4760
testb $0x1, %al
jne 0x3f85
jmp 0x4108
leaq 0x9e0(%rsp), %rdi
leaq 0xa14(%rsp), %rsi
callq 0x47e0
movq %rax, 0x68(%rsp)
jmp 0x3fa1
movq 0x68(%rsp), %rax
movq $0x1, (%rax)
jmp 0x4133
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x3fe9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
leaq 0x670(%rsp), %rdi
callq 0x31d0
leaq 0x66f(%rsp), %rdi
callq 0x3330
jmp 0x455d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x4525
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x4518
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x40b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x409d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x4090
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
leaq 0x1c8(%rsp), %rdi
callq 0x31d0
leaq 0x180(%rsp), %rdi
callq 0x31d0
leaq 0x17f(%rsp), %rdi
callq 0x3330
leaq 0x1a8(%rsp), %rdi
callq 0x31d0
leaq 0x1a7(%rsp), %rdi
callq 0x3330
jmp 0x450b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
jmp 0x450b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x31d0
jmp 0x450b
leaq 0x9e0(%rsp), %rdi
leaq 0xa14(%rsp), %rsi
callq 0x47e0
movq %rax, 0x60(%rsp)
jmp 0x4124
movq 0x60(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
leaq 0x460(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x30c0
jmp 0x414a
leaq 0x460(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x30c0
jmp 0x4161
leaq 0x460(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x30c0
jmp 0x4178
jmp 0x417a
movq 0x460(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x460(%rsp,%rax), %rdi
callq 0x3600
movb %al, 0x5f(%rsp)
jmp 0x4199
movb 0x5f(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x41a8
jmp 0x4350
leaq 0x460(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x30c0
jmp 0x41bf
leaq 0x440(%rsp), %rdi
movl $0x4e, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x3420
cmpq $-0x1, %rax
jne 0x4306
leaq 0x128(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x3160
jmp 0x41f6
movl 0x668(%rsp), %edx
leaq 0x718(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x6a20
movl %eax, 0x58(%rsp)
jmp 0x4218
movl 0x58(%rsp), %eax
movl %eax, 0xa14(%rsp)
leaq 0x128(%rsp), %rdi
callq 0x31d0
leaq 0x9e0(%rsp), %rdi
leaq 0xa14(%rsp), %rsi
callq 0x4780
movq %rax, 0x50(%rsp)
jmp 0x424c
movq 0x50(%rsp), %rax
movq %rax, 0x120(%rsp)
leaq 0x9e0(%rsp), %rdi
callq 0x47b0
movq %rax, 0x118(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0x4760
testb $0x1, %al
jne 0x4289
jmp 0x42d9
leaq 0x9e0(%rsp), %rdi
leaq 0xa14(%rsp), %rsi
callq 0x47e0
movq %rax, 0x48(%rsp)
jmp 0x42a5
movq 0x48(%rsp), %rax
movq $0x1, (%rax)
jmp 0x4304
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x710(%rsp)
movl %eax, 0x70c(%rsp)
leaq 0x128(%rsp), %rdi
callq 0x31d0
jmp 0x450b
leaq 0x9e0(%rsp), %rdi
leaq 0xa14(%rsp), %rsi
callq 0x47e0
movq %rax, 0x40(%rsp)
jmp 0x42f5
movq 0x40(%rsp), %rax
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x4306
leaq 0x460(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x30c0
jmp 0x431d
leaq 0x460(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x30c0
jmp 0x4334
leaq 0x460(%rsp), %rdi
leaq 0x440(%rsp), %rsi
callq 0x30c0
jmp 0x434b
jmp 0x417a
movq 0x18c71(%rip), %rdi     # 0x1cfc8
leaq 0x10d4a(%rip), %rsi     # 0x150a8
callq 0x32c0
movq %rax, 0x38(%rsp)
jmp 0x436a
movq 0x38(%rsp), %rdi
movl 0x668(%rsp), %esi
callq 0x35a0
movq %rax, 0x30(%rsp)
jmp 0x4382
movq 0x30(%rsp), %rdi
movq 0x18c2a(%rip), %rsi     # 0x1cfb8
callq 0x3310
jmp 0x4395
leaq 0x10d0c(%rip), %rsi     # 0x150a8
leaq 0x1e8(%rsp), %rdi
callq 0x32c0
movq %rax, 0x28(%rsp)
jmp 0x43b0
movq 0x28(%rsp), %rdi
movl 0x668(%rsp), %esi
callq 0x35a0
movq %rax, 0x20(%rsp)
jmp 0x43c8
movq 0x20(%rsp), %rdi
movq 0x18be4(%rip), %rsi     # 0x1cfb8
callq 0x3310
jmp 0x43db
leaq 0x9e0(%rsp), %rdi
callq 0x48d0
movq %rax, 0x110(%rsp)
leaq 0x9e0(%rsp), %rdi
callq 0x47b0
movq %rax, 0x108(%rsp)
leaq 0x110(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0x4900
testb $0x1, %al
jne 0x4423
jmp 0x44b1
leaq 0x110(%rsp), %rdi
callq 0x4920
movl (%rax), %esi
leaq 0x1e8(%rsp), %rdi
callq 0x35a0
movq %rax, 0x18(%rsp)
jmp 0x4446
movq 0x18(%rsp), %rdi
leaq 0x11135(%rip), %rsi     # 0x15587
callq 0x32c0
movq %rax, 0x10(%rsp)
jmp 0x445e
leaq 0x110(%rsp), %rdi
callq 0x4920
movq 0x10(%rsp), %rdi
movq 0x8(%rax), %rsi
callq 0x32a0
movq %rax, 0x8(%rsp)
jmp 0x4480
movq 0x8(%rsp), %rdi
movq 0x18b2c(%rip), %rsi     # 0x1cfb8
callq 0x3310
jmp 0x4493
jmp 0x4495
leaq 0x110(%rsp), %rdi
xorl %esi, %esi
callq 0x4940
movq %rax, 0x100(%rsp)
jmp 0x43f0
movq 0x18b20(%rip), %rdi     # 0x1cfd8
leaq 0x668(%rsp), %rsi
callq 0x31c0
jmp 0x44c7
jmp 0x3e5f
movl $0x0, 0xa24(%rsp)
movl $0x1, 0x690(%rsp)
leaq 0x1e8(%rsp), %rdi
callq 0x34c0
leaq 0x440(%rsp), %rdi
callq 0x31d0
leaq 0x460(%rsp), %rdi
callq 0x3100
jmp 0x4534
leaq 0x1e8(%rsp), %rdi
callq 0x34c0
leaq 0x440(%rsp), %rdi
callq 0x31d0
leaq 0x460(%rsp), %rdi
callq 0x3100
jmp 0x455d
leaq 0x718(%rsp), %rdi
callq 0x6120
leaq 0x9e0(%rsp), %rdi
callq 0x4980
movl 0xa24(%rsp), %eax
addq $0xa28, %rsp            # imm = 0xA28
retq
leaq 0x718(%rsp), %rdi
callq 0x6120
leaq 0x9e0(%rsp), %rdi
callq 0x4980
movq 0x710(%rsp), %rdi
callq 0x35c0
nopw %cs:(%rax,%rax)
nop