// File: 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:
subq $0x268, %rsp            # imm = 0x268
movq %rdi, 0x260(%rsp)
movq %rsi, 0x258(%rsp)
leaq 0x238(%rsp), %rdi
callq 0x3370
leaq 0x200(%rsp), %rdi
callq 0x5880
movl $0x0, 0x1fc(%rsp)
movl $0x0, 0x1f8(%rsp)
movl $0x0, 0x1f4(%rsp)
movq 0x260(%rsp), %rdi
callq 0x3400
movb %al, 0x127(%rsp)
jmp 0x46c8
movb 0x127(%rsp), %al
testb $0x1, %al
jne 0x46d8
jmp 0x4d4a
jmp 0x46da
movq 0x260(%rsp), %rdi
leaq 0x238(%rsp), %rsi
callq 0x3070
movq %rax, 0x118(%rsp)
jmp 0x46f9
movq 0x118(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x3330
movb %al, 0x117(%rsp)
jmp 0x4719
movb 0x117(%rsp), %al
testb $0x1, %al
jne 0x4729
jmp 0x4d48
xorl %eax, %eax
movl %eax, %esi
leaq 0x238(%rsp), %rdi
callq 0x34d0
movq %rax, 0x108(%rsp)
jmp 0x4744
movq 0x108(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x40, %eax
jne 0x47a7
movq 0x258(%rsp), %rdi
leaq 0x238(%rsp), %rsi
callq 0x3250
movq %rax, 0x100(%rsp)
jmp 0x4773
movq 0x100(%rsp), %rdi
movq 0x881e(%rip), %rsi      # 0xcfa0
callq 0x32b0
jmp 0x4789
jmp 0x4d43
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1e8(%rsp)
movl %eax, 0x1e4(%rsp)
jmp 0x4fa7
movl 0x1fc(%rsp), %eax
incl %eax
movl %eax, 0x1fc(%rsp)
movl $0xf0, %edi
callq 0x3280
movq %rax, 0xf8(%rsp)
jmp 0x47cb
movq 0xf8(%rsp), %rdi
leaq 0x238(%rsp), %rsi
callq 0x5160
jmp 0x47e2
movq 0xf8(%rsp), %rax
movq %rax, 0x1d8(%rsp)
movq 0x1d8(%rsp), %rsi
movb $0x0, 0x197(%rsp)
leaq 0x1b8(%rsp), %rdi
callq 0x5890
jmp 0x4811
leaq 0x4cec(%rip), %rsi      # 0x9504
leaq 0x1b8(%rsp), %rdi
movq $-0x1, %rdx
callq 0x3440
movq %rax, 0xf0(%rsp)
jmp 0x4836
movq 0xf0(%rsp), %rcx
movb $0x1, %al
cmpq $-0x1, %rcx
movb %al, 0xef(%rsp)
jne 0x48a7
movq 0x1d8(%rsp), %rsi
leaq 0x198(%rsp), %rdi
callq 0x5890
jmp 0x4864
movb $0x1, 0x197(%rsp)
leaq 0x4c94(%rip), %rsi      # 0x9507
leaq 0x198(%rsp), %rdi
movq $-0x1, %rdx
callq 0x3440
movq %rax, 0xe0(%rsp)
jmp 0x4891
movq 0xe0(%rsp), %rax
cmpq $-0x1, %rax
setne %al
movb %al, 0xef(%rsp)
movb 0xef(%rsp), %al
movb %al, 0xdf(%rsp)
testb $0x1, 0x197(%rsp)
jne 0x48c1
jmp 0x48ce
leaq 0x198(%rsp), %rdi
callq 0x3180
leaq 0x1b8(%rsp), %rdi
callq 0x3180
movb 0xdf(%rsp), %al
testb $0x1, %al
jne 0x48eb
jmp 0x4c78
movq 0x1d8(%rsp), %rsi
leaq 0x150(%rsp), %rdi
callq 0x5890
jmp 0x4902
leaq 0x170(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0x4150
jmp 0x4919
leaq 0x150(%rsp), %rdi
callq 0x3180
leaq 0x200(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x58c0
movq %rax, 0xd0(%rsp)
jmp 0x4945
movq 0xd0(%rsp), %rax
movq %rax, 0x148(%rsp)
leaq 0x200(%rsp), %rdi
callq 0x5910
movq %rax, 0x140(%rsp)
leaq 0x148(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0x58f0
testb $0x1, %al
jne 0x4988
jmp 0x4a9d
movq 0x1d8(%rsp), %rax
movq %rax, 0xc0(%rsp)
leaq 0x200(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x5940
movq %rax, 0xc8(%rsp)
jmp 0x49b7
movq 0xc8(%rsp), %rax
movq 0xc0(%rsp), %rcx
movq %rcx, (%rax)
jmp 0x4c66
movq 0xf8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1e8(%rsp)
movl %eax, 0x1e4(%rsp)
movl $0xf0, %esi
callq 0x3290
jmp 0x4fa7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1e8(%rsp)
movl %eax, 0x1e4(%rsp)
jmp 0x4a3f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1e8(%rsp)
movl %eax, 0x1e4(%rsp)
testb $0x1, 0x197(%rsp)
jne 0x4a30
jmp 0x4a3d
leaq 0x198(%rsp), %rdi
callq 0x3180
jmp 0x4a3f
leaq 0x1b8(%rsp), %rdi
callq 0x3180
jmp 0x4fa7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1e8(%rsp)
movl %eax, 0x1e4(%rsp)
leaq 0x150(%rsp), %rdi
callq 0x3180
jmp 0x4fa7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1e8(%rsp)
movl %eax, 0x1e4(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x3180
jmp 0x4fa7
leaq 0x200(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x5940
movq %rax, 0xb8(%rsp)
jmp 0x4abc
movq 0xb8(%rsp), %rax
movq (%rax), %rdi
callq 0x5970
movb %al, 0xb7(%rsp)
jmp 0x4ad5
movb 0xb7(%rsp), %al
testb $0x1, %al
jne 0x4ae2
jmp 0x4b1b
movq 0x1d8(%rsp), %rdi
callq 0x5970
movb %al, 0xb6(%rsp)
jmp 0x4af8
movb 0xb6(%rsp), %al
testb $0x1, %al
jne 0x4b05
jmp 0x4b1b
movl 0x1f4(%rsp), %eax
addl $0x2, %eax
movl %eax, 0x1f4(%rsp)
jmp 0x4bca
movl 0x1f8(%rsp), %eax
addl $0x2, %eax
movl %eax, 0x1f8(%rsp)
movq 0x258(%rsp), %rax
movq %rax, 0xa0(%rsp)
leaq 0x200(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x5940
movq %rax, 0xa8(%rsp)
jmp 0x4b5b
movq 0xa0(%rsp), %rdi
movq 0xa8(%rsp), %rax
movq (%rax), %rsi
callq 0x5580
movq %rax, 0x98(%rsp)
jmp 0x4b7d
movq 0x98(%rsp), %rdi
movq 0x8414(%rip), %rsi      # 0xcfa0
callq 0x32b0
jmp 0x4b93
movq 0x258(%rsp), %rdi
movq 0x1d8(%rsp), %rsi
callq 0x5580
movq %rax, 0x90(%rsp)
jmp 0x4bb2
movq 0x90(%rsp), %rdi
movq 0x83df(%rip), %rsi      # 0xcfa0
callq 0x32b0
jmp 0x4bc8
jmp 0x4bca
leaq 0x200(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x5940
movq %rax, 0x88(%rsp)
jmp 0x4be9
movq 0x88(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x80(%rsp)
cmpq $0x0, %rax
je 0x4c21
movq 0x80(%rsp), %rdi
callq 0x5800
movq 0x80(%rsp), %rdi
movl $0xf0, %esi
callq 0x3290
movq 0x1d8(%rsp), %rax
movq %rax, 0x78(%rsp)
cmpq $0x0, %rax
je 0x4c4d
movq 0x78(%rsp), %rdi
callq 0x5800
movq 0x78(%rsp), %rdi
movl $0xf0, %esi
callq 0x3290
leaq 0x200(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x5990
jmp 0x4c64
jmp 0x4c66
leaq 0x170(%rsp), %rdi
callq 0x3180
jmp 0x4d41
movq 0x1d8(%rsp), %rdi
callq 0x5970
movb %al, 0x77(%rsp)
jmp 0x4c8b
movb 0x77(%rsp), %al
testb $0x1, %al
jne 0x4d02
jmp 0x4c95
movl 0x1f8(%rsp), %eax
incl %eax
movl %eax, 0x1f8(%rsp)
movq 0x258(%rsp), %rdi
movq 0x1d8(%rsp), %rsi
callq 0x5580
movq %rax, 0x68(%rsp)
jmp 0x4cc1
movq 0x68(%rsp), %rdi
movq 0x82d3(%rip), %rsi      # 0xcfa0
callq 0x32b0
jmp 0x4cd4
movq 0x1d8(%rsp), %rax
movq %rax, 0x60(%rsp)
cmpq $0x0, %rax
je 0x4d00
movq 0x60(%rsp), %rdi
callq 0x5800
movq 0x60(%rsp), %rdi
movl $0xf0, %esi
callq 0x3290
jmp 0x4d3f
movq 0x1d8(%rsp), %rax
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0x4d2e
movq 0x58(%rsp), %rdi
callq 0x5800
movq 0x58(%rsp), %rdi
movl $0xf0, %esi
callq 0x3290
movl 0x1f4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1f4(%rsp)
jmp 0x4d41
jmp 0x4d43
jmp 0x46da
jmp 0x4d4a
leaq 0x8660(%rip), %rax      # 0xd3b1
testb $0x1, (%rax)
je 0x4ede
cvtsi2ssl 0x1f8(%rsp), %xmm0
cvtsi2ssl 0x1fc(%rsp), %xmm1
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x4774(%rip), %xmm0     # 0x94f0
subsd %xmm1, %xmm0
movsd 0x4770(%rip), %xmm1     # 0x94f8
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x13c(%rsp)
movq 0x8250(%rip), %rdi      # 0xcff0
leaq 0x4763(%rip), %rsi      # 0x950a
callq 0x3260
movq %rax, 0x50(%rsp)
jmp 0x4db3
movq 0x50(%rsp), %rdi
movq 0x81e1(%rip), %rsi      # 0xcfa0
callq 0x32b0
jmp 0x4dc6
movq 0x8223(%rip), %rdi      # 0xcff0
leaq 0x474d(%rip), %rsi      # 0x9521
callq 0x3260
movq %rax, 0x48(%rsp)
jmp 0x4de0
movq 0x48(%rsp), %rdi
movl 0x1fc(%rsp), %esi
callq 0x3460
movq %rax, 0x40(%rsp)
jmp 0x4df8
movq 0x40(%rsp), %rdi
movq 0x819c(%rip), %rsi      # 0xcfa0
callq 0x32b0
jmp 0x4e0b
movq 0x81de(%rip), %rdi      # 0xcff0
leaq 0x4716(%rip), %rsi      # 0x952f
callq 0x3260
movq %rax, 0x38(%rsp)
jmp 0x4e25
movq 0x38(%rsp), %rdi
movl 0x1f4(%rsp), %esi
callq 0x3460
movq %rax, 0x30(%rsp)
jmp 0x4e3d
movq 0x30(%rsp), %rdi
movq 0x8157(%rip), %rsi      # 0xcfa0
callq 0x32b0
jmp 0x4e50
movq 0x8199(%rip), %rdi      # 0xcff0
leaq 0x46e3(%rip), %rsi      # 0x9541
callq 0x3260
movq %rax, 0x28(%rsp)
jmp 0x4e6a
movq 0x28(%rsp), %rdi
movl 0x1f8(%rsp), %esi
callq 0x3460
movq %rax, 0x20(%rsp)
jmp 0x4e82
movq 0x20(%rsp), %rdi
movq 0x8112(%rip), %rsi      # 0xcfa0
callq 0x32b0
jmp 0x4e95
movss 0x13c(%rsp), %xmm0
movq 0x814b(%rip), %rdi      # 0xcff0
callq 0x31d0
movq %rax, 0x18(%rsp)
jmp 0x4eb1
movq 0x18(%rsp), %rdi
leaq 0x4693(%rip), %rsi      # 0x9550
callq 0x3260
movq %rax, 0x10(%rsp)
jmp 0x4ec9
movq 0x10(%rsp), %rdi
movq 0x80cb(%rip), %rsi      # 0xcfa0
callq 0x32b0
jmp 0x4edc
jmp 0x4ede
movq 0x258(%rsp), %rdi
callq 0x3390
jmp 0x4eed
leaq 0x200(%rsp), %rdi
callq 0x59c0
movq %rax, 0x130(%rsp)
leaq 0x200(%rsp), %rdi
callq 0x5910
movq %rax, 0x128(%rsp)
leaq 0x130(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x59f0
testb $0x1, %al
jne 0x4f32
jmp 0x4f78
leaq 0x130(%rsp), %rdi
callq 0x5a10
movq 0x20(%rax), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x4f67
movq 0x8(%rsp), %rdi
callq 0x5800
movq 0x8(%rsp), %rdi
movl $0xf0, %esi
callq 0x3290
jmp 0x4f69
leaq 0x130(%rsp), %rdi
callq 0x5a30
jmp 0x4f02
leaq 0x200(%rsp), %rdi
callq 0x5a60
leaq 0x200(%rsp), %rdi
callq 0x5a80
leaq 0x238(%rsp), %rdi
callq 0x3180
addq $0x268, %rsp            # imm = 0x268
retq
leaq 0x200(%rsp), %rdi
callq 0x5a80
leaq 0x238(%rsp), %rdi
callq 0x3180
movq 0x1e8(%rsp), %rdi
callq 0x3470
nop