// File: CMU-SAFARI[P]optimal-seed-solver/thresholdSolver.cc
// Function: ThresholdSolver::solve(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
int ThresholdSolver::solve(string read)
{
	int index = this->index;
	if(verbose)
	{
		cout << "Reading read #" << index << ": " << read << endl;
		cout.flush();
		cout << "Original length: " << read.length() << endl;
	}

	int minLength = tree.getHashLength();
	int maxLength = tree.getFullLength();

	int pos = 0;
	int count = 0;

	bool pass = true;

	int ll = 0;
	int totalfreq = 0;

	this->read = read;

	for (int i = 0; i < thresholdVec.size(); i++) {

		int currLength = maxLength;

		if(read.length() - pos < maxLength)
		{
			currLength = read.length() - pos;
			if(currLength <= minLength)
			{
				// Read too small
				if(verbose)
					cout << "Read too small" << endl;
				pass = false;
				break;
			}
		}

		string seed = read.substr(pos, currLength);
		if(verbose)
			cout << "Position " << pos << "." << endl;

		tree.query(seed, thresholdVec[i]);
		int len = tree.effectiveLength();
		int freq = tree.frequency();

		if(verbose)
			cout << "Effective length: " << len << " Frequency: " << freq << endl;

		if(freq <= thresholdVec[i])
		{
			//Case 1
			//this works
			if(verbose)
				cout << "Frequency is <= threshold." << endl;
			pos += len;
			//freqTable[index][count] = freq;
			//seedLenTable[index][count] = len;
		}
		else if(tree.isLeaf())
		{
			//Case 2
			//hits leaf before threshold - ok
			if(verbose)
				cout << "Hit leaf before threshold." << endl;
			pos += len;
			//freqTable[index][count] = freq;
			//seedLenTable[index][count] = len;
		}
		else
		{
			//Case 3
			//does not meet threhold, not leaf - fail
			if(verbose)
				cout << "Leaf does not meet threshold = fail." << endl;
			pass = false;
			break;
		}

		count++;
		if (pos == read.length())
		{
			if(verbose)
				cout << "Position at read length. Success." << endl;
			break;
		}
		if (pos > read.length() - minLength)
		{
			if(verbose)
				cout << "Next read size too small." << endl;
			pass = false;
			break;
		}
		totalfreq += freq;
	}

	if(!pass)
	{
		//Did not pass - calculate letters left
		/*
		ll = read.length() - pos;
		if(verbose)
			cout << ll << " letters left." << endl;
		lettersLeft[index] = ll;
		*/
		return -1;
	}
	if(verbose)
		cout << "Finished read at position " << pos << " from " << read.length() << " with totalFrequency " << totalfreq << ".\n" << endl;

	return totalfreq;
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rsi, 0xa8(%rsp)
movq %rdi, 0x148(%rsp)
movq %rsi, 0x140(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0xb0(%rsp)
movl 0x428(%rax), %ecx
movl %ecx, 0x13c(%rsp)
testb $0x1, 0xcc(%rax)
je 0x925c
movq 0x19e08(%rip), %rdi     # 0x22fc8
leaq 0xffb1(%rip), %rsi      # 0x19178
callq 0x32c0
movq %rax, %rdi
movl 0x13c(%rsp), %esi
callq 0x35a0
movq %rax, %rdi
leaq 0x10591(%rip), %rsi     # 0x19776
callq 0x32c0
movq 0xa8(%rsp), %rsi
movq %rax, %rdi
callq 0x3280
movq %rax, %rdi
movq 0x19db4(%rip), %rsi     # 0x22fb8
callq 0x3310
movq 0x19db8(%rip), %rdi     # 0x22fc8
callq 0x31f0
movq 0x19dac(%rip), %rdi     # 0x22fc8
leaq 0xff64(%rip), %rsi      # 0x19187
callq 0x32c0
movq 0xa8(%rsp), %rdi
movq %rax, 0xa0(%rsp)
callq 0x34d0
movq 0xa0(%rsp), %rdi
movq %rax, %rsi
callq 0x30e0
movq %rax, %rdi
movq 0x19d61(%rip), %rsi     # 0x22fb8
callq 0x3310
movq 0xb0(%rsp), %rdi
addq $0xd0, %rdi
callq 0xe220
movq 0xb0(%rsp), %rdi
movl %eax, 0x138(%rsp)
addq $0xd0, %rdi
callq 0xe230
movq 0xb0(%rsp), %rdi
movq 0xa8(%rsp), %rsi
movl %eax, 0x134(%rsp)
movl $0x0, 0x130(%rsp)
movl $0x0, 0x12c(%rsp)
movb $0x1, 0x12b(%rsp)
movl $0x0, 0x124(%rsp)
movl $0x0, 0x120(%rsp)
addq $0x430, %rdi            # imm = 0x430
callq 0x3050
movl $0x0, 0x11c(%rsp)
movq 0xb0(%rsp), %rdi
movslq 0x11c(%rsp), %rax
movq %rax, 0x98(%rsp)
addq $0x450, %rdi            # imm = 0x450
callq 0x5550
movq %rax, %rcx
movq 0x98(%rsp), %rax
cmpq %rcx, %rax
jae 0x98c8
movq 0xa8(%rsp), %rdi
movl 0x134(%rsp), %eax
movl %eax, 0x118(%rsp)
callq 0x34d0
movslq 0x130(%rsp), %rcx
subq %rcx, %rax
movslq 0x134(%rsp), %rcx
cmpq %rcx, %rax
jae 0x93c9
movq 0xa8(%rsp), %rdi
callq 0x34d0
movslq 0x130(%rsp), %rcx
subq %rcx, %rax
movl %eax, 0x118(%rsp)
movl 0x118(%rsp), %eax
cmpl 0x138(%rsp), %eax
jg 0x93c7
movq 0xb0(%rsp), %rax
testb $0x1, 0xcc(%rax)
je 0x93ba
movq 0x19c29(%rip), %rdi     # 0x22fc8
leaq 0xfdf3(%rip), %rsi      # 0x19199
callq 0x32c0
movq %rax, %rdi
movq 0x19c03(%rip), %rsi     # 0x22fb8
callq 0x3310
movb $0x0, 0x12b(%rsp)
jmp 0x98c8
jmp 0x93c9
movq 0xa8(%rsp), %rsi
movslq 0x130(%rsp), %rdx
movslq 0x118(%rsp), %rcx
leaq 0xf8(%rsp), %rdi
callq 0x32f0
movq 0xb0(%rsp), %rax
testb $0x1, 0xcc(%rax)
je 0x948d
movq 0x19bbe(%rip), %rdi     # 0x22fc8
leaq 0xfd97(%rip), %rsi      # 0x191a8
callq 0x32c0
movq %rax, 0x90(%rsp)
jmp 0x9420
movq 0x90(%rsp), %rdi
movl 0x130(%rsp), %esi
callq 0x35a0
movq %rax, 0x88(%rsp)
jmp 0x943e
movq 0x88(%rsp), %rdi
leaq 0x10300(%rip), %rsi     # 0x1974d
callq 0x32c0
movq %rax, 0x80(%rsp)
jmp 0x945c
movq 0x80(%rsp), %rdi
movq 0x19b4d(%rip), %rsi     # 0x22fb8
callq 0x3310
jmp 0x9472
jmp 0x948d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
jmp 0x98b6
movq 0xb0(%rsp), %rax
addq $0xd0, %rax
movq %rax, 0x78(%rsp)
leaq 0xc8(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x3150
jmp 0x94b7
movq 0xb0(%rsp), %rdi
addq $0x450, %rdi            # imm = 0x450
movslq 0x11c(%rsp), %rsi
callq 0xa000
movq 0x78(%rsp), %rdi
movl (%rax), %edx
leaq 0xc8(%rsp), %rsi
callq 0xe240
jmp 0x94e9
leaq 0xc8(%rsp), %rdi
callq 0x31c0
movq 0xb0(%rsp), %rdi
addq $0xd0, %rdi
callq 0xe480
movl %eax, 0x74(%rsp)
jmp 0x9510
movq 0xb0(%rsp), %rdi
movl 0x74(%rsp), %eax
movl %eax, 0xc4(%rsp)
addq $0xd0, %rdi
callq 0xe4a0
movl %eax, 0x70(%rsp)
jmp 0x9535
movq 0xb0(%rsp), %rax
movl 0x70(%rsp), %ecx
movl %ecx, 0xc0(%rsp)
testb $0x1, 0xcc(%rax)
je 0x95f2
movq 0x19a6c(%rip), %rdi     # 0x22fc8
leaq 0xfc4f(%rip), %rsi      # 0x191b2
callq 0x32c0
movq %rax, 0x68(%rsp)
jmp 0x956f
movq 0x68(%rsp), %rdi
movl 0xc4(%rsp), %esi
callq 0x35a0
movq %rax, 0x60(%rsp)
jmp 0x9587
movq 0x60(%rsp), %rdi
leaq 0xfc32(%rip), %rsi      # 0x191c5
callq 0x32c0
movq %rax, 0x58(%rsp)
jmp 0x959f
movq 0x58(%rsp), %rdi
movl 0xc0(%rsp), %esi
callq 0x35a0
movq %rax, 0x50(%rsp)
jmp 0x95b7
movq 0x50(%rsp), %rdi
movq 0x199f5(%rip), %rsi     # 0x22fb8
callq 0x3310
jmp 0x95ca
jmp 0x95f2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x31c0
jmp 0x98b6
movq 0xb0(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, 0x4c(%rsp)
addq $0x450, %rdi            # imm = 0x450
movslq 0x11c(%rsp), %rsi
callq 0xa000
movq %rax, %rcx
movl 0x4c(%rsp), %eax
cmpl (%rcx), %eax
jg 0x967e
movq 0xb0(%rsp), %rax
testb $0x1, 0xcc(%rax)
je 0x9664
movq 0x1998c(%rip), %rdi     # 0x22fc8
leaq 0xfb8f(%rip), %rsi      # 0x191d2
callq 0x32c0
movq %rax, 0x40(%rsp)
jmp 0x964f
movq 0x40(%rsp), %rdi
movq 0x1995d(%rip), %rsi     # 0x22fb8
callq 0x3310
jmp 0x9662
jmp 0x9664
movl 0xc4(%rsp), %eax
addl 0x130(%rsp), %eax
movl %eax, 0x130(%rsp)
jmp 0x9753
movq 0xb0(%rsp), %rdi
addq $0xd0, %rdi
callq 0xe4f0
movb %al, 0x3f(%rsp)
jmp 0x9698
movb 0x3f(%rsp), %al
testb $0x1, %al
jne 0x96a2
jmp 0x96f9
movq 0xb0(%rsp), %rax
testb $0x1, 0xcc(%rax)
je 0x96e2
movq 0x1990e(%rip), %rdi     # 0x22fc8
leaq 0xfb2c(%rip), %rsi      # 0x191ed
callq 0x32c0
movq %rax, 0x30(%rsp)
jmp 0x96cd
movq 0x30(%rsp), %rdi
movq 0x198df(%rip), %rsi     # 0x22fb8
callq 0x3310
jmp 0x96e0
jmp 0x96e2
movl 0xc4(%rsp), %eax
addl 0x130(%rsp), %eax
movl %eax, 0x130(%rsp)
jmp 0x9751
movq 0xb0(%rsp), %rax
testb $0x1, 0xcc(%rax)
je 0x9739
movq 0x198b7(%rip), %rdi     # 0x22fc8
leaq 0xfaf0(%rip), %rsi      # 0x19208
callq 0x32c0
movq %rax, 0x28(%rsp)
jmp 0x9724
movq 0x28(%rsp), %rdi
movq 0x19888(%rip), %rsi     # 0x22fb8
callq 0x3310
jmp 0x9737
jmp 0x9739
movb $0x0, 0x12b(%rsp)
movl $0x2, 0xbc(%rsp)
jmp 0x9882
jmp 0x9753
movq 0xa8(%rsp), %rdi
movl 0x12c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x12c(%rsp)
movslq 0x130(%rsp), %rax
movq %rax, 0x20(%rsp)
callq 0x34d0
movq %rax, %rcx
movq 0x20(%rsp), %rax
cmpq %rcx, %rax
jne 0x97db
movq 0xb0(%rsp), %rax
testb $0x1, 0xcc(%rax)
je 0x97cb
movq 0x19825(%rip), %rdi     # 0x22fc8
leaq 0xfa83(%rip), %rsi      # 0x1922d
callq 0x32c0
movq %rax, 0x18(%rsp)
jmp 0x97b6
movq 0x18(%rsp), %rdi
movq 0x197f6(%rip), %rsi     # 0x22fb8
callq 0x3310
jmp 0x97c9
jmp 0x97cb
movl $0x2, 0xbc(%rsp)
jmp 0x9882
movq 0xa8(%rsp), %rdi
movslq 0x130(%rsp), %rax
movq %rax, 0x10(%rsp)
callq 0x34d0
movq %rax, %rcx
movq 0x10(%rsp), %rax
movslq 0x138(%rsp), %rdx
subq %rdx, %rcx
cmpq %rcx, %rax
jbe 0x9862
movq 0xb0(%rsp), %rax
testb $0x1, 0xcc(%rax)
je 0x984d
movq 0x197a3(%rip), %rdi     # 0x22fc8
leaq 0xfa23(%rip), %rsi      # 0x1924f
callq 0x32c0
movq %rax, 0x8(%rsp)
jmp 0x9838
movq 0x8(%rsp), %rdi
movq 0x19774(%rip), %rsi     # 0x22fb8
callq 0x3310
jmp 0x984b
jmp 0x984d
movb $0x0, 0x12b(%rsp)
movl $0x2, 0xbc(%rsp)
jmp 0x9882
movl 0xc0(%rsp), %eax
addl 0x120(%rsp), %eax
movl %eax, 0x120(%rsp)
movl $0x0, 0xbc(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0x31c0
movl 0xbc(%rsp), %eax
testl %eax, %eax
je 0x989e
jmp 0x989c
jmp 0x98c8
jmp 0x98a0
movl 0x11c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x11c(%rsp)
jmp 0x92ed
leaq 0xf8(%rsp), %rdi
callq 0x31c0
jmp 0x999e
testb $0x1, 0x12b(%rsp)
jne 0x98e2
movl $0xffffffff, 0x154(%rsp) # imm = 0xFFFFFFFF
jmp 0x998f
movq 0xb0(%rsp), %rax
testb $0x1, 0xcc(%rax)
je 0x9981
movq 0x196ca(%rip), %rdi     # 0x22fc8
leaq 0xf964(%rip), %rsi      # 0x19269
callq 0x32c0
movq %rax, %rdi
movl 0x130(%rsp), %esi
callq 0x35a0
movq %rax, %rdi
leaq 0xf961(%rip), %rsi      # 0x19284
callq 0x32c0
movq 0xa8(%rsp), %rdi
movq %rax, (%rsp)
callq 0x34d0
movq (%rsp), %rdi
movq %rax, %rsi
callq 0x30e0
movq %rax, %rdi
leaq 0xf93c(%rip), %rsi      # 0x1928b
callq 0x32c0
movq %rax, %rdi
movl 0x120(%rsp), %esi
callq 0x35a0
movq %rax, %rdi
leaq 0xf6e4(%rip), %rsi      # 0x19051
callq 0x32c0
movq %rax, %rdi
movq 0x1963c(%rip), %rsi     # 0x22fb8
callq 0x3310
movl 0x120(%rsp), %eax
movl %eax, 0x154(%rsp)
movl 0x154(%rsp), %eax
addq $0x158, %rsp            # imm = 0x158
retq
movq 0xf0(%rsp), %rdi
callq 0x35c0
nopl (%rax,%rax)