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

	AnalyzeBasic solver;

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

	if (argc == 4) {
		solver.generateHash(argv[1], atoi(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
		for (int i = 0; i < seedNum; i++) {
			int interval = read.length() / seedNum;
			string seed = read.substr(i * interval, solver.getLength() );
			frequency = solver.checkFreq(seed);
			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
			for (int i = 0; i < seedNum; i++) {
				if (read.find('N') == string::npos) {
					int interval = read.length() / seedNum;
					string seed = read.substr(i * interval, solver.getLength() );
					frequency = solver.checkFreq(seed);
					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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x858, %rsp            # imm = 0x858
movq %rsi, %rbx
movl %edi, %r14d
leaq 0x60(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x370(%rsp), %rdi
callq 0x31a8
leal -0x5(%r14), %eax
cmpl $-0x3, %eax
jbe 0x2ba8
cmpl $0x4, %r14d
jne 0x2697
movq 0x8(%rbx), %rsi
leaq 0x108(%rsp), %rdi
leaq 0x168(%rsp), %rdx
callq 0x2cee
movq 0x18(%rbx), %rdi
callq 0x2330
leaq 0x370(%rsp), %rdi
leaq 0x108(%rsp), %rsi
movl %eax, %edx
callq 0x3214
leaq 0x108(%rsp), %rdi
callq 0x2100
movq 0x10(%rbx), %rsi
leaq 0xe8(%rsp), %rdi
leaq 0x168(%rsp), %rdx
callq 0x2cee
leaq 0x370(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x33b4
leaq 0xe8(%rsp), %rdi
callq 0x2100
jmp 0x2b7d
movq 0x592a(%rip), %rdi      # 0x7fc8
leaq 0x29cb(%rip), %rsi      # 0x5070
callq 0x2200
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x2200
leaq 0x29c1(%rip), %rsi      # 0x507e
movq %rax, %rdi
callq 0x2200
movq 0x8(%rbx), %rsi
leaq 0xc8(%rsp), %rdi
leaq 0x168(%rsp), %rdx
callq 0x2cee
leaq 0x370(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x3460
leaq 0xc8(%rsp), %rdi
callq 0x2100
movq 0x58c1(%rip), %rdi      # 0x7fc8
leaq 0x297f(%rip), %rsi      # 0x508d
callq 0x2200
movq 0x58be(%rip), %rdi      # 0x7fd8
leaq 0xc(%rsp), %rsi
callq 0x2140
leaq 0x168(%rsp), %rdi
callq 0x2250
movq 0x10(%rbx), %rsi
leaq 0x168(%rsp), %rbp
pushq $0x8
popq %rdx
movq %rbp, %rdi
callq 0x2150
leaq 0x28(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movq 0x10(%rbx), %rsi
leaq 0x600(%rsp), %rbx
movq %rbx, %rdi
callq 0x21f0
leaq 0x292d(%rip), %rsi      # 0x50a1
movq %rbx, %rdi
callq 0x2340
movq %rax, %rbx
leaq 0x658(%rsp), %rdi
callq 0x23a0
leaq 0xa8(%rsp), %rdi
leaq 0x17(%rsp), %rdx
movq %rbx, %rsi
callq 0x2cee
leaq 0x28fb(%rip), %rsi      # 0x50a3
leaq 0x88(%rsp), %rdi
leaq 0x16(%rsp), %rdx
callq 0x2cee
leaq 0x38(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
leaq 0x88(%rsp), %rdx
callq 0x2d29
movq 0x38(%rsp), %rsi
leaq 0x658(%rsp), %rdi
pushq $0x10
popq %rdx
callq 0x2030
leaq 0x38(%rsp), %rdi
callq 0x2100
leaq 0x88(%rsp), %rdi
callq 0x2100
leaq 0xa8(%rsp), %rdi
callq 0x2100
leaq 0x58(%rsp), %rbx
pushq $0x4e
popq %r13
cmpl $0x0, 0xc(%rsp)
jle 0x2b59
movq %rbx, %rdi
callq 0x2ed8
movq 0x168(%rsp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
xorl %esi, %esi
callq 0x2390
movq %rbp, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x22d0
movq %rbp, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2070
movq %rbp, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2070
xorl %r14d, %r14d
movslq 0xc(%rsp), %rbp
cmpl %ebp, %r14d
jge 0x292f
movq 0x20(%rsp), %r13
leaq 0x370(%rsp), %rdi
callq 0x3580
leaq 0x38(%rsp), %r12
movl %eax, %ecx
movq %r13, %rax
xorl %edx, %edx
divq %rbp
imull %r14d, %eax
movslq %eax, %rdx
movl %ecx, %ecx
movq %r12, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2230
leaq 0x148(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x22e0
pushq $0x4e
popq %r13
leaq 0x370(%rsp), %rdi
movq %r15, %rsi
callq 0x3536
movl %eax, 0x10(%rsp)
movq %r15, %rdi
callq 0x2100
movq %rbx, %rdi
leaq 0x10(%rsp), %rsi
callq 0x2f06
leaq 0x60(%rsp), %rcx
cmpq %rcx, %rax
je 0x2909
movq %rbx, %rdi
leaq 0x10(%rsp), %rsi
callq 0x2d90
incq (%rax)
jmp 0x291d
movq %rbx, %rdi
leaq 0x10(%rsp), %rsi
callq 0x2d90
movq $0x1, (%rax)
leaq 0x38(%rsp), %rdi
callq 0x2100
incl %r14d
jmp 0x2868
leaq 0x168(%rsp), %rbp
movq %rbp, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2070
leaq 0x38(%rsp), %r14
movq %rbp, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2070
movq %rbp, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2070
movq 0x168(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x2, 0x188(%rsp,%rax)
jne 0x2aa0
movq %rbp, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2070
xorl %ebp, %ebp
cmpl 0xc(%rsp), %ebp
leaq 0x18(%rsp), %rdi
jge 0x2a6f
movl %r13d, %esi
xorl %edx, %edx
callq 0x22b0
cmpq $-0x1, %rax
jne 0x2a68
movq %rbx, %r15
movq 0x20(%rsp), %r13
movslq 0xc(%rsp), %rbx
leaq 0x370(%rsp), %rdi
callq 0x3580
movl %eax, %ecx
movq %r13, %rax
xorl %edx, %edx
divq %rbx
imull %ebp, %eax
movslq %eax, %rdx
movl %ecx, %ecx
movq %r14, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2230
leaq 0x128(%rsp), %rdi
movq %r14, %rsi
callq 0x22e0
pushq $0x4e
popq %r13
movq %r15, %rbx
leaq 0x370(%rsp), %rdi
leaq 0x128(%rsp), %r15
movq %r15, %rsi
callq 0x3536
movl %eax, 0x10(%rsp)
movq %r15, %rdi
callq 0x2100
movq %rbx, %rdi
leaq 0x10(%rsp), %rsi
callq 0x2f06
leaq 0x60(%rsp), %rcx
cmpq %rcx, %rax
je 0x2a4c
movq %rbx, %rdi
leaq 0x10(%rsp), %rsi
callq 0x2d90
incq (%rax)
jmp 0x2a60
movq %rbx, %rdi
leaq 0x10(%rsp), %rsi
callq 0x2d90
movq $0x1, (%rax)
movq %r14, %rdi
callq 0x2100
incl %ebp
jmp 0x298c
leaq 0x168(%rsp), %rbp
movq %rdi, %r15
movq %rbp, %rdi
movq %r15, %rsi
callq 0x2070
movq %rbp, %rdi
movq %r15, %rsi
callq 0x2070
movq %rbp, %rdi
movq %r15, %rsi
callq 0x2070
jmp 0x2963
movq 0x5521(%rip), %rdi      # 0x7fc8
leaq 0x25fc(%rip), %rsi      # 0x50aa
callq 0x2200
movl 0xc(%rsp), %esi
movq %rax, %rdi
callq 0x23b0
movq %rax, %rdi
callq 0x2110
leaq 0x658(%rsp), %rdi
leaq 0x25d4(%rip), %rsi      # 0x50aa
callq 0x2200
movl 0xc(%rsp), %esi
movq %rax, %rdi
callq 0x23b0
movq %rax, %rdi
callq 0x2110
movq 0x70(%rsp), %r13
leaq 0x60(%rsp), %rax
cmpq %rax, %r13
je 0x2b3f
movl 0x20(%r13), %esi
leaq 0x658(%rsp), %rdi
callq 0x23b0
movq %rax, %rdi
leaq 0x265d(%rip), %rsi      # 0x5176
callq 0x2200
movq 0x28(%r13), %rsi
movq %rax, %rdi
callq 0x2170
movq %rax, %rdi
callq 0x2110
movq %r13, %rdi
callq 0x2190
movq %rax, %r13
jmp 0x2af4
movq 0x5492(%rip), %rdi      # 0x7fd8
leaq 0xc(%rsp), %rsi
callq 0x2140
pushq $0x4e
popq %r13
jmp 0x2816
leaq 0x658(%rsp), %rdi
callq 0x2310
leaq 0x18(%rsp), %rdi
callq 0x2100
leaq 0x168(%rsp), %rdi
callq 0x20b0
leaq 0x370(%rsp), %rdi
callq 0x31ee
leaq 0x58(%rsp), %rdi
callq 0x2dea
xorl %eax, %eax
addq $0x858, %rsp            # imm = 0x858
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x5441(%rip), %rdi      # 0x7ff0
leaq 0x244e(%rip), %rsi      # 0x5004
callq 0x2200
movq %rax, %rdi
callq 0x2110
movq 0x5426(%rip), %rdi      # 0x7ff0
leaq 0x246c(%rip), %rsi      # 0x503d
callq 0x2200
movq %rax, %rdi
callq 0x2110
pushq $0x1
popq %rdi
callq 0x2270
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x2100
jmp 0x2bf8
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x2100
jmp 0x2c0a
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
jmp 0x2ca1
jmp 0x2ca8
movq %rax, %rbx
jmp 0x2cb8
movq %rax, %rbx
jmp 0x2cc2
jmp 0x2c67
jmp 0x2c67
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
jmp 0x2c59
jmp 0x2c67
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
jmp 0x2c59
jmp 0x2c67
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
callq 0x2100
jmp 0x2ccf
jmp 0x2c67
movq %rax, %rbx
jmp 0x2cdc
movq %rax, %rbx
jmp 0x2ccf
jmp 0x2ca8
jmp 0x2c99
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
jmp 0x2c92
jmp 0x2ca8
jmp 0x2c99
jmp 0x2ca8
jmp 0x2ca8
jmp 0x2c99
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
callq 0x2100
jmp 0x2c9c
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x2100
jmp 0x2cab
movq %rax, %rbx
leaq 0x658(%rsp), %rdi
callq 0x2310
leaq 0x18(%rsp), %rdi
callq 0x2100
leaq 0x168(%rsp), %rdi
callq 0x20b0
leaq 0x370(%rsp), %rdi
callq 0x31ee
leaq 0x58(%rsp), %rdi
callq 0x2dea
movq %rbx, %rdi
callq 0x23e0