// File: /workspace/github_cpp_makefile_star2_O2/bcthomas[P]shrinksam/src/process_stream.cpp
// Function: process_shrunk_unpaired(std::basic_ifstream<char, std::char_traits<char>>&, std::basic_ofstream<char, std::char_traits<char>>&)
void process_shrunk_unpaired(std::ifstream &in, std::ofstream &shr_out) {
	string line;
	unordered_map<std::string, Shrinksam::Sam*> reads; // string -> Sam object (ptr)

	int total_reads = 0;
	int output_reads = 0;
	int discarded_reads = 0;
	if (in.is_open()) {
		while(getline(in,line)) {
			if (line[0] == '@') {           // header so just write to output
				shr_out << line << endl;
			} else {
				++total_reads;
				Sam *s = new Sam(line);

				if ( (s->get_qname().rfind("/1") != std::string::npos) ||
					 (s->get_qname().rfind("/2") != std::string::npos)) {
					// found a "/1" read or a "/2" read
					string read_base = parse_read_name(s->get_qname());
					auto it = reads.find(read_base);
					if (it == reads.end()) { // not in reads
						reads[read_base] = s; // store the read for later
					} else { // have already seen mate, so print this pair and remove from reads
						if (reads[read_base]->unmapped() && s->unmapped()) {
							discarded_reads += 2;
						} else { // one or the other read mapped, so keep both
							output_reads += 2;
							shr_out << *reads[read_base] << endl;
							shr_out << *s << endl;
						}
						delete reads[read_base]; // free memory for stored Sam object
						delete s;                // free memory for current Sam object
						reads.erase(read_base);  // remove key
					}
				} else {
					// Found nothing to pair on! Only include if sam
					// flag does NOT have bit 4 set
					if (!s->unmapped()) {
						++output_reads;
						shr_out << *s << endl;
						delete s; // free memory for current Sam object
					} else {
						delete s; // free memory for current Sam object
						++discarded_reads;
					}
			    }
			}
		} // end of while() loop
	}
	
	if (Shrinksam::verbose_flag) {
		float percent = (1.0 - ((float) output_reads / (float) total_reads)) * 100;
		cerr << "--- Shrink summary ---" << endl;
		cerr << "Total Reads: " << total_reads << endl;
		cerr << "Discarded Reads: " << discarded_reads << endl;
		cerr << "Output Reads: " << output_reads << endl;
		cerr << percent << "% shrunk" << endl;
	}

    // close files
    shr_out.close();
	// delete anything left in reads map
	for(auto it = reads.begin(); it != reads.end(); ++it)
		delete it->second;
	reads.empty();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rsi, %rbx
movq %rdi, %r12
leaq 0x78(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x60(%rsp), %rax
movq %rax, -0x30(%rax)
movq $0x1, -0x28(%rax)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rax)
movl $0x3f800000, -0x10(%rax) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
addq $0x78, %rdi
callq 0x2070
xorl %r15d, %r15d
movl $0x0, %ebp
movl $0x0, %r14d
testb %al, %al
je 0x312d
movl $0x0, 0x4(%rsp)
leaq 0x68(%rsp), %r13
movl $0x0, 0x8(%rsp)
movl $0x0, 0xc(%rsp)
movq %r12, %rdi
movq %r13, %rsi
callq 0x2050
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x311f
movq 0x68(%rsp), %rax
cmpb $0x40, (%rax)
jne 0x2f27
movq %rbx, %rdi
movq %r13, %rsi
callq 0x2200
movq %rax, %rdi
callq 0x2110
jmp 0x2eeb
movl $0xf0, %edi
callq 0x2230
movq %rax, %r15
movq %rax, %rdi
movq %r13, %rsi
callq 0x331a
leaq 0x10(%rsp), %rbp
movq %rbp, %rdi
movq %r15, %rsi
callq 0x22a0
movq %rbp, %rdi
leaq 0x24e7(%rip), %rsi      # 0x5440
pushq $-0x1
popq %rdx
callq 0x2340
incl 0xc(%rsp)
cmpq $-0x1, %rax
jne 0x2fe7
leaq 0x88(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x22a0
movq %r14, %rdi
leaq 0x24bb(%rip), %rsi      # 0x5443
pushq $-0x1
popq %rdx
callq 0x2340
movq %rax, %rbp
movq %r14, %rdi
callq 0x20f0
leaq 0x10(%rsp), %rdi
callq 0x20f0
cmpq $-0x1, %rbp
jne 0x2ff1
testb $0x4, 0x20(%r15)
jne 0x3089
movq %rbx, %rdi
movq %r15, %rsi
callq 0x3567
movq %rax, %rdi
callq 0x2110
incl 0x8(%rsp)
movq %r15, %rdi
callq 0x36c0
movl $0xf0, %esi
movq %r15, %rdi
callq 0x2240
jmp 0x2eeb
leaq 0x10(%rsp), %rdi
callq 0x20f0
leaq 0x88(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x22a0
leaq 0x10(%rsp), %rbp
movq %rbp, %rdi
movq %r14, %rsi
callq 0x2bd6
movq %r14, %rdi
callq 0x20f0
leaq 0x30(%rsp), %rdi
movq %rbp, %rsi
callq 0x3bcc
testq %rax, %rax
je 0x30a7
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x3cee
movq (%rax), %rax
testb $0x4, 0x20(%rax)
je 0x304d
testb $0x4, 0x20(%r15)
jne 0x30bb
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x3cee
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x3567
movq %rax, %rdi
callq 0x2110
movq %rbx, %rdi
movq %r15, %rsi
callq 0x3567
movq %rax, %rdi
callq 0x2110
addl $0x2, 0x8(%rsp)
jmp 0x30c0
movq %r15, %rdi
callq 0x36c0
movl $0xf0, %esi
movq %r15, %rdi
callq 0x2240
incl 0x4(%rsp)
jmp 0x2eeb
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x3cee
movq %r15, (%rax)
jmp 0x3110
addl $0x2, 0x4(%rsp)
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x3cee
movq (%rax), %r14
testq %r14, %r14
je 0x30df
movq %r14, %rdi
callq 0x36c0
movl $0xf0, %esi
movq %r14, %rdi
callq 0x2240
movq %r15, %rdi
callq 0x36c0
movl $0xf0, %esi
movq %r15, %rdi
callq 0x2240
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x407e
leaq 0x10(%rsp), %rdi
callq 0x20f0
jmp 0x2eeb
movl 0x8(%rsp), %ebp
movl 0x4(%rsp), %r15d
movl 0xc(%rsp), %r14d
leaq 0x51ed(%rip), %rax      # 0x8321
cmpb $0x1, (%rax)
jne 0x3215
movq 0x4eac(%rip), %rdi      # 0x7ff0
leaq 0x22fb(%rip), %rsi      # 0x5446
callq 0x2210
movq %rax, %rdi
callq 0x2110
movq 0x4e91(%rip), %rdi      # 0x7ff0
leaq 0x22f7(%rip), %rsi      # 0x545d
callq 0x2210
movq %rax, %rdi
movl %r14d, %esi
callq 0x2360
movq %rax, %rdi
callq 0x2110
movq 0x4e6b(%rip), %rdi      # 0x7ff0
leaq 0x22df(%rip), %rsi      # 0x546b
callq 0x2210
movq %rax, %rdi
movl %r15d, %esi
callq 0x2360
movq %rax, %rdi
callq 0x2110
movq 0x4e45(%rip), %rdi      # 0x7ff0
leaq 0x22cb(%rip), %rsi      # 0x547d
callq 0x2210
movq %rax, %rdi
movl %ebp, %esi
callq 0x2360
movq %rax, %rdi
callq 0x2110
cvtsi2ss %ebp, %xmm0
cvtsi2ss %r14d, %xmm1
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x224e(%rip), %xmm1     # 0x5430
subsd %xmm0, %xmm1
mulsd 0x224a(%rip), %xmm1     # 0x5438
cvtsd2ss %xmm1, %xmm0
movq 0x4df7(%rip), %rdi      # 0x7ff0
callq 0x2190
leaq 0x2287(%rip), %rsi      # 0x548c
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2110
movq %rbx, %rdi
callq 0x22c0
leaq 0x40(%rsp), %r14
movq (%r14), %r14
testq %r14, %r14
je 0x324a
movq 0x28(%r14), %rbx
testq %rbx, %rbx
je 0x323b
movq %rbx, %rdi
callq 0x36c0
movl $0xf0, %esi
movq %rbx, %rdi
callq 0x2240
jmp 0x3222
leaq 0x30(%rsp), %rdi
callq 0x3a78
leaq 0x68(%rsp), %rdi
callq 0x20f0
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
jmp 0x329d
jmp 0x32be
jmp 0x3295
jmp 0x3295
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x20f0
jmp 0x3298
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x20f0
jmp 0x32c1
jmp 0x32be
movq %rax, %rbx
movl $0xf0, %esi
movq %r15, %rdi
callq 0x2240
jmp 0x32c1
jmp 0x32be
jmp 0x32be
jmp 0x32be
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x3a78
leaq 0x68(%rsp), %rdi
callq 0x20f0
movq %rbx, %rdi
callq 0x2370
nop