// File: ridgelab[P]Kmer-SSR/src/FindSSRs.cpp
// Function: FindSSRs::processInput()
void FindSSRs::processInput() // produce
{
	ifstream fasta_file;
	fasta_file.open(this->args->getInFileName().c_str());

	// init (set the data_size of) the progress bar
	uint32_t init_size = this->args->getInFileName() == "/dev/stdin" ? 0 : calculateDataSizeFromFasta(fasta_file);
	this->progress_bar->initialize(init_size);

	string header = "";
	string sequence = "";
	string line = "";
	while (getline(fasta_file, line))
	{
		if (line.size())
		{
			if (line[0] != '>') // line is a sequence
			{
				this->progress_bar->updateProgress(1, false); // +1 for the '\n'

				for (uint32_t i = 0; i < line.size(); ++i) // -1 because we don't want to add the '\n' to the sequence
				{
					//sequence = sequence + (char) toupper(line[i]);
					sequence += (char) toupper(line[i]);
					//if (!isspace(line[i])) // TODO
					//{
					//	sequence += (char) toupper(line[i]);
					//}
					//else
					//{
					//	// update the progress bar based on the space
					//}
				}
			}
			else // line is a header
			{
				this->processSequence(header,sequence);

				header = line.substr(1, string::npos);
				sequence = "";
				
				this->progress_bar->updateProgress(header.size() + 2, false); // +1 for the '\n', +1 for the '>'
			}
		}
		else // empty line
		{
			this->progress_bar->updateProgress(1, false); // +1 for the '\n'
		}
		
	}
	
	this->processSequence(header,sequence); // catch the last sequence

	fasta_file.close(); // close the input file

	// put some NULL tasks in the TaskQueue, signalling the threads they can quit when they encounter one
	switch (this->args->getNumThreads())
	{
		case 1:
			break;
		default:
			for (uint32_t i = 1; i < this->args->getNumThreads(); ++i)
			{
				this->tasks->add(nullptr);
			}
			break;
	}

	// if there are plenty of tasks left (more than 2 tasks, excluding the dummy tasks, per thread)
	if (this->tasks->size() > (this->args->getNumThreads() * 3))
	{
		// the main thread becomes a consumer for a while
		SSRcontainer* ssrs = new SSRcontainer();
		Task* task = nullptr;

		// but only until each thread will have 2 tasks left (excluding the dummy task)
		while (this->tasks->size() > (this->args->getNumThreads() * 3))
		{
			// get a task
			task = this->tasks->get(); // get a task
		
			// fulfill the task, add the results to the SSRcontainer, attempt to write them to file
			ssrs->add(task->getID(), findSSRs(task, this->args, this->atomicity_checker));
			ssrs->writeToFile(this->out_file, false, true); // false means it won't block if it can't write, true means it will clear the SSRcontainer if it wrote
		
			// let the user know we've made some progress
			progress_bar->updateProgress(task->size(), true);

			// delete the ask now that we've completed it
			delete task;
		}

		// if we didn't write everything, let's do it now
		if (!ssrs->empty())
		{
			ssrs->writeToFile(this->out_file, true, false); // true means it will block until it can write, false means it won't clear the SSRcontainer when finished (because we're about to delete the thing anyway right after this)
		}

		delete ssrs;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x400, %rsp            # imm = 0x400
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x338(%rbp)
leaq -0x210(%rbp), %rdi
callq 0x4450
movq -0x338(%rbp), %rax
movq (%rax), %rsi
leaq -0x230(%rbp), %rdi
callq 0x19ee0
jmp 0x1130e
leaq -0x230(%rbp), %rdi
callq 0x4160
movq %rax, %rsi
leaq -0x210(%rbp), %rdi
movl $0x8, %edx
callq 0x4230
jmp 0x11330
leaq -0x230(%rbp), %rdi
callq 0x4788
movq -0x338(%rbp), %rax
movq (%rax), %rsi
leaq -0x260(%rbp), %rdi
callq 0x19ee0
jmp 0x11354
leaq 0xfe9f(%rip), %rsi      # 0x211fa
leaq -0x260(%rbp), %rdi
callq 0x13520
movb %al, -0x339(%rbp)
jmp 0x1136f
movb -0x339(%rbp), %al
testb $0x1, %al
jne 0x1137b
jmp 0x11385
xorl %eax, %eax
movl %eax, -0x340(%rbp)
jmp 0x113a7
leaq -0x210(%rbp), %rdi
callq 0x12050
movl %eax, -0x344(%rbp)
jmp 0x11399
movl -0x344(%rbp), %eax
movl %eax, -0x340(%rbp)
jmp 0x113a7
movl -0x340(%rbp), %eax
movl %eax, -0x348(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x4788
movl -0x348(%rbp), %ecx
movq -0x338(%rbp), %rax
movl %ecx, -0x240(%rbp)
movq 0x28(%rax), %rdi
movl -0x240(%rbp), %esi
callq 0x20770
jmp 0x113e3
leaq -0x281(%rbp), %rdi
movq %rdi, -0x350(%rbp)
callq 0x4700
movq -0x350(%rbp), %rdx
leaq 0xfc8c(%rip), %rsi      # 0x21090
leaq -0x280(%rbp), %rdi
callq 0x6da0
jmp 0x11412
leaq -0x281(%rbp), %rdi
callq 0x4410
leaq -0x2a9(%rbp), %rdi
movq %rdi, -0x358(%rbp)
callq 0x4700
movq -0x358(%rbp), %rdx
leaq 0xfc51(%rip), %rsi      # 0x21090
leaq -0x2a8(%rbp), %rdi
callq 0x6da0
jmp 0x1144d
leaq -0x2a9(%rbp), %rdi
callq 0x4410
leaq -0x2d1(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0x4700
movq -0x360(%rbp), %rdx
leaq 0xfc16(%rip), %rsi      # 0x21090
leaq -0x2d0(%rbp), %rdi
callq 0x6da0
jmp 0x11488
leaq -0x2d1(%rbp), %rdi
callq 0x4410
leaq -0x210(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
callq 0x40a0
movq %rax, -0x368(%rbp)
jmp 0x114b0
movq -0x368(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x44e0
movb %al, -0x369(%rbp)
jmp 0x114ce
movb -0x369(%rbp), %al
testb $0x1, %al
jne 0x114dd
jmp 0x1176f
leaq -0x2d0(%rbp), %rdi
callq 0x4260
cmpq $0x0, %rax
je 0x1174f
xorl %eax, %eax
movl %eax, %esi
leaq -0x2d0(%rbp), %rdi
callq 0x4770
movq %rax, -0x378(%rbp)
jmp 0x1150c
movq -0x378(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3e, %eax
je 0x116a0
movq -0x338(%rbp), %rax
movq 0x28(%rax), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x207e0
jmp 0x11538
movl $0x0, -0x2d8(%rbp)
movl -0x2d8(%rbp), %eax
movq %rax, -0x380(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x4260
movq %rax, %rcx
movq -0x380(%rbp), %rax
cmpq %rcx, %rax
jae 0x1169b
movl -0x2d8(%rbp), %eax
movl %eax, %esi
leaq -0x2d0(%rbp), %rdi
callq 0x4770
movq %rax, -0x388(%rbp)
jmp 0x1158b
movq -0x388(%rbp), %rax
movsbl (%rax), %edi
callq 0x4730
movsbl %al, %esi
leaq -0x2a8(%rbp), %rdi
callq 0x4220
jmp 0x115ab
jmp 0x115ad
movl -0x2d8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2d8(%rbp)
jmp 0x11542
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x238(%rbp)
movl %eax, -0x23c(%rbp)
jmp 0x11b34
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x238(%rbp)
movl %eax, -0x23c(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x4788
jmp 0x11b34
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x238(%rbp)
movl %eax, -0x23c(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x4788
jmp 0x11b34
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x238(%rbp)
movl %eax, -0x23c(%rbp)
leaq -0x281(%rbp), %rdi
callq 0x4410
jmp 0x11b34
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x238(%rbp)
movl %eax, -0x23c(%rbp)
leaq -0x2a9(%rbp), %rdi
callq 0x4410
jmp 0x11b28
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x238(%rbp)
movl %eax, -0x23c(%rbp)
leaq -0x2d1(%rbp), %rdi
callq 0x4410
jmp 0x11b1c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x238(%rbp)
movl %eax, -0x23c(%rbp)
jmp 0x11b10
jmp 0x1174d
movq -0x338(%rbp), %rdi
leaq -0x280(%rbp), %rsi
leaq -0x2a8(%rbp), %rdx
callq 0x120c0
jmp 0x116bc
leaq -0x2f8(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
movl $0x1, %edx
movq $-0x1, %rcx
callq 0x43c0
jmp 0x116dd
leaq -0x280(%rbp), %rdi
leaq -0x2f8(%rbp), %rsi
movq %rsi, -0x390(%rbp)
callq 0x44b0
movq -0x390(%rbp), %rdi
callq 0x4788
leaq 0xf986(%rip), %rsi      # 0x21090
leaq -0x2a8(%rbp), %rdi
callq 0x4550
jmp 0x11718
movq -0x338(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x398(%rbp)
leaq -0x280(%rbp), %rdi
callq 0x4260
movq -0x398(%rbp), %rdi
movl %eax, %esi
addl $0x2, %esi
xorl %edx, %edx
callq 0x207e0
jmp 0x1174b
jmp 0x1174d
jmp 0x1176a
movq -0x338(%rbp), %rax
movq 0x28(%rax), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x207e0
jmp 0x11768
jmp 0x1176a
jmp 0x11494
movq -0x338(%rbp), %rdi
leaq -0x280(%rbp), %rsi
leaq -0x2a8(%rbp), %rdx
callq 0x120c0
jmp 0x1178b
leaq -0x210(%rbp), %rdi
callq 0x40c0
jmp 0x11799
movq -0x338(%rbp), %rax
movq (%rax), %rdi
callq 0x19d30
movl %eax, -0x39c(%rbp)
jmp 0x117b0
movl -0x39c(%rbp), %eax
subl $0x1, %eax
jne 0x117bf
jmp 0x117bd
jmp 0x11827
movl $0x1, -0x2fc(%rbp)
movq -0x338(%rbp), %rax
movl -0x2fc(%rbp), %ecx
movl %ecx, -0x3a4(%rbp)
movq (%rax), %rdi
callq 0x19d30
movl %eax, -0x3a0(%rbp)
jmp 0x117ec
movl -0x3a4(%rbp), %eax
movl -0x3a0(%rbp), %ecx
cmpl %ecx, %eax
jae 0x11825
movq -0x338(%rbp), %rax
movq 0x38(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x16a90
jmp 0x11812
jmp 0x11814
movl -0x2fc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2fc(%rbp)
jmp 0x117c9
jmp 0x11827
movq -0x338(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x16a50
movl %eax, -0x3a8(%rbp)
jmp 0x1183f
movq -0x338(%rbp), %rax
movq (%rax), %rdi
callq 0x19d30
movl %eax, -0x3ac(%rbp)
jmp 0x11856
movl -0x3a8(%rbp), %eax
movl -0x3ac(%rbp), %ecx
imull $0x3, %ecx, %ecx
cmpl %ecx, %eax
jbe 0x11ad7
movl $0x8, %edi
callq 0x43a0
movq %rax, -0x3b8(%rbp)
jmp 0x11880
movq -0x3b8(%rbp), %rdi
callq 0x5ac0
jmp 0x1188e
movq -0x3b8(%rbp), %rax
movq %rax, -0x308(%rbp)
movq $0x0, -0x310(%rbp)
movq -0x338(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x16a50
movl %eax, -0x3bc(%rbp)
jmp 0x118bf
movq -0x338(%rbp), %rax
movq (%rax), %rdi
callq 0x19d30
movl %eax, -0x3c0(%rbp)
jmp 0x118d6
movl -0x3bc(%rbp), %eax
movl -0x3c0(%rbp), %ecx
imull $0x3, %ecx, %ecx
cmpl %ecx, %eax
jbe 0x11a62
movq -0x338(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x16af0
movq %rax, -0x3c8(%rbp)
jmp 0x11906
movq -0x3c8(%rbp), %rax
movq %rax, -0x310(%rbp)
movq -0x308(%rbp), %rax
movq %rax, -0x3d0(%rbp)
movq -0x310(%rbp), %rsi
leaq -0x330(%rbp), %rdi
callq 0x16370
jmp 0x11937
movq -0x338(%rbp), %rax
movq -0x310(%rbp), %rdi
movq (%rax), %rsi
movq 0x30(%rax), %rdx
callq 0x12750
movq %rax, -0x3d8(%rbp)
jmp 0x1195a
movq -0x3d8(%rbp), %rdx
movq -0x3d0(%rbp), %rdi
leaq -0x330(%rbp), %rsi
callq 0x5e60
jmp 0x11976
leaq -0x330(%rbp), %rdi
callq 0x4788
movq -0x338(%rbp), %rax
movq -0x308(%rbp), %rdi
movq 0x20(%rax), %rsi
xorl %edx, %edx
movl $0x1, %ecx
callq 0x61c0
jmp 0x119a2
movq -0x338(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x3e8(%rbp)
movq -0x310(%rbp), %rdi
callq 0x163d0
movl %eax, -0x3dc(%rbp)
jmp 0x119c8
movl -0x3dc(%rbp), %esi
movq -0x3e8(%rbp), %rdi
movl $0x1, %edx
callq 0x207e0
jmp 0x119e1
movq -0x310(%rbp), %rax
movq %rax, -0x3f0(%rbp)
cmpq $0x0, %rax
je 0x11a12
movq -0x3f0(%rbp), %rdi
callq 0x16110
movq -0x3f0(%rbp), %rdi
movl $0x48, %esi
callq 0x43b0
jmp 0x118a7
movq -0x3b8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x238(%rbp)
movl %eax, -0x23c(%rbp)
movl $0x8, %esi
callq 0x43b0
jmp 0x11b10
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x238(%rbp)
movl %eax, -0x23c(%rbp)
leaq -0x330(%rbp), %rdi
callq 0x4788
jmp 0x11b10
movq -0x308(%rbp), %rdi
callq 0x5cb0
movb %al, -0x3f1(%rbp)
jmp 0x11a76
movb -0x3f1(%rbp), %al
testb $0x1, %al
jne 0x11aa4
jmp 0x11a82
movq -0x338(%rbp), %rax
movq -0x308(%rbp), %rdi
movq 0x20(%rax), %rsi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x61c0
jmp 0x11aa2
jmp 0x11aa4
movq -0x308(%rbp), %rax
movq %rax, -0x400(%rbp)
cmpq $0x0, %rax
je 0x11ad5
movq -0x400(%rbp), %rdi
callq 0x5b10
movq -0x400(%rbp), %rdi
movl $0x8, %esi
callq 0x43b0
jmp 0x11ad7
leaq -0x2d0(%rbp), %rdi
callq 0x4788
leaq -0x2a8(%rbp), %rdi
callq 0x4788
leaq -0x280(%rbp), %rdi
callq 0x4788
leaq -0x210(%rbp), %rdi
callq 0x40f0
addq $0x400, %rsp            # imm = 0x400
popq %rbp
retq
leaq -0x2d0(%rbp), %rdi
callq 0x4788
leaq -0x2a8(%rbp), %rdi
callq 0x4788
leaq -0x280(%rbp), %rdi
callq 0x4788
leaq -0x210(%rbp), %rdi
callq 0x40f0
movq -0x238(%rbp), %rdi
callq 0x46e0
nopl (%rax)