// File: /workspace/github_cpp_makefile_star2_O2/simonrharris[P]SKA/src/sk_alleles.cpp
// Function: allelesToKmers(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&, long const&)
int allelesToKmers(const std::vector < std::string > & alleles, const long & kmerlen)
{

	const std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();//start the clock

	int substringlength=(kmerlen*2)+1;

	for (int s = 0; s < alleles.size(); ++s){

		std::cout << "Creating split kmers for " << alleles[s] << std::endl;

		int numAlleles=0;
		std::vector < std::string > alleleNames;	

		if(countSequencesinFasta(alleles[s], numAlleles)){return 1;}//count the number of sequences in the file

		// Create the kmer map
		std::unordered_map < std::string, std::string > kmerMap;

		int alleleNumber=0;
		
		igzstream gzfileStream;
		if(openGzFileStream(alleles[s], gzfileStream)){return 1;}

		while (gzfileStream.peek()!=EOF){

			std::string alleleName;
			std::string sequence;
			sequence.reserve(10000);

			if(readNextFastaSequence(gzfileStream, alleles[s], alleleName, sequence)){return 1;}

			alleleNames.push_back(alleleName);

			if(IUPACToN(sequence)){return 1;}//convert any IUPAC charaxcters to N and reject any unrecognised characters
			
			std::stringstream sequencestream;
			sequencestream << sequence;//convert the sequence to stringstream
			std::string subsequence;
			
			while (std::getline(sequencestream, subsequence, 'N')){
				
				if (subsequence.length()<substringlength){
					continue;
				}

				for (int i=0; i<subsequence.length()-(substringlength-1); ++i){
					std::string kmer=subsequence.substr(i,substringlength);
					
					reverseComplementIfMin(kmer);
					
					char base;
					extractMiddleBase(kmer, base);
					
					addKmerToStringMap(kmerMap, kmer, base, alleleNumber, numAlleles);
				}
		
    		}
    		alleleNumber++;
		}
 		gzfileStream.close();//close the file
	
 		std::unordered_map < std::vector < bool >,  std::vector < std::string > > revKmerMap;

		if(reverseKmerMap(kmerMap, revKmerMap, numAlleles)){return 1;}

		if(printMergedKmerFile(revKmerMap, alleles[s]+".skf", alleleNames, kmerlen)){return 1;}

	}

	printDuration(start);//stop the clock
	
	return 0;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x558, %rsp            # imm = 0x558
movq %rsi, %rbx
movq %rdi, %rbp
callq 0x5050
movq %rax, 0x60(%rsp)
movq %rbx, 0x68(%rsp)
movl (%rbx), %eax
leal 0x1(,%rax,2), %ecx
addl %eax, %eax
movslq %ecx, %r12
movslq %eax, %r15
movq 0x298fb(%rip), %rdi     # 0x35fb8
leaq 0x1910d(%rip), %rsi     # 0x257d1
pushq $0x1
popq %rax
movl %eax, 0xc(%rsp)
leaq 0x78(%rsp), %r14
leaq 0x110(%rsp), %r13
xorl %ebx, %ebx
movq %rbp, 0x10(%rsp)
movq 0x8(%rbp), %rax
subq (%rbp), %rax
sarq $0x5, %rax
cmpq %rbx, %rax
jbe 0xca76
callq 0x53f0
movq %rbx, 0x70(%rsp)
shlq $0x5, %rbx
movq (%rbp), %rsi
addq %rbx, %rsi
movq %rax, %rdi
callq 0x53a0
movq %rax, %rdi
callq 0x51c0
andl $0x0, 0x8(%rsp)
andq $0x0, 0x30(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq (%rbp), %rdi
movq %rbx, 0x18(%rsp)
addq %rbx, %rdi
leaq 0x8(%rsp), %rsi
callq 0x6b3d
testl %eax, %eax
jne 0xcab1
leaq 0xe8(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq $0x1, 0xc0(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rax)
movl $0x3f800000, 0xd8(%rsp) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
leaq 0x2b8(%rsp), %rbx
movq %rbx, %rdi
callq 0x6d0a
movq 0x10(%rsp), %rax
movq (%rax), %rdi
addq 0x18(%rsp), %rdi
movq %rbx, %rsi
pushq $0x1
popq %rdx
callq 0x74af
testl %eax, %eax
jne 0xca97
xorl %ebx, %ebx
leaq 0x440(%rsp), %rdi
callq 0x5140
cmpl $-0x1, %eax
je 0xc967
leaq 0xa8(%rsp), %rax
movq %rax, 0x98(%rsp)
andq $0x0, 0xa0(%rsp)
xorl %ecx, %ecx
movb %cl, 0xa8(%rsp)
leaq 0x50(%rsp), %rax
movq %rax, 0x40(%rsp)
andq $0x0, 0x48(%rsp)
movb %cl, 0x50(%rsp)
movl $0x2710, %esi           # imm = 0x2710
leaq 0x40(%rsp), %rbp
movq %rbp, %rdi
callq 0x55f0
movq 0x10(%rsp), %rax
movq (%rax), %rsi
addq 0x18(%rsp), %rsi
leaq 0x2b8(%rsp), %rdi
leaq 0x98(%rsp), %rdx
movq %rbp, %rcx
callq 0x67b1
testl %eax, %eax
jne 0xc855
leaq 0x20(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x77fc
leaq 0x40(%rsp), %rdi
callq 0x65ee
testl %eax, %eax
je 0xc87c
xorl %ebp, %ebp
leaq 0x40(%rsp), %rdi
callq 0x5778
leaq 0x98(%rsp), %rdi
callq 0x5778
testb %bpl, %bpl
jne 0xc7ae
jmp 0xca97
leaq 0x130(%rsp), %rdi
callq 0x52b0
leaq 0x140(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x53a0
leaq 0x88(%rsp), %rax
movq %rax, 0x78(%rsp)
andq $0x0, 0x80(%rsp)
movb $0x0, 0x88(%rsp)
leaq 0x130(%rsp), %rdi
movq %r14, %rsi
pushq $0x4e
popq %rdx
callq 0x56e0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0xc948
movq 0x80(%rsp), %rax
cmpq %r12, %rax
jb 0xc8b9
xorl %ebp, %ebp
subq %r15, %rax
cmpq %rbp, %rax
jbe 0xc8b9
movq %r13, %rdi
movq %r14, %rsi
movq %rbp, %rdx
movq %r12, %rcx
callq 0x5420
movq %r13, %rdi
callq 0x6578
movq %r13, %rdi
leaq 0x7(%rsp), %rsi
callq 0x7c51
movsbl 0x7(%rsp), %edx
movl 0x8(%rsp), %r8d
leaq 0xb8(%rsp), %rdi
movq %r13, %rsi
movl %ebx, %ecx
callq 0xc5b9
movq %r13, %rdi
callq 0x5778
incq %rbp
movq 0x80(%rsp), %rax
jmp 0xc8e9
incl %ebx
movq %r14, %rdi
callq 0x5778
leaq 0x130(%rsp), %rdi
callq 0x5320
movb $0x1, %bpl
jmp 0xc857
leaq 0x2b8(%rsp), %rdi
callq 0x6db4
leaq 0x160(%rsp), %rax
movq %rax, 0x130(%rsp)
movq $0x1, 0x138(%rsp)
leaq 0x140(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movl $0x3f800000, 0x150(%rsp) # imm = 0x3F800000
movups %xmm0, 0x18(%rax)
movl 0x8(%rsp), %edx
leaq 0xb8(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0xc328
testl %eax, %eax
leaq 0xf0(%rsp), %rdi
jne 0xca8a
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rsi
addq (%rax), %rsi
leaq 0x1b338(%rip), %rdx     # 0x27d22
callq 0xbe9e
movq 0x68(%rsp), %rax
movl (%rax), %ecx
leaq 0x130(%rsp), %rdi
leaq 0xf0(%rsp), %rbp
movq %rbp, %rsi
leaq 0x20(%rsp), %rdx
callq 0x80d4
movl %eax, %ebx
movq %rbp, %rdi
callq 0x5778
leaq 0x130(%rsp), %rdi
callq 0xbf2a
leaq 0x2b8(%rsp), %rdi
callq 0x6dea
leaq 0xb8(%rsp), %rdi
callq 0xbfa8
leaq 0x20(%rsp), %rdi
callq 0x911e
movq 0x70(%rsp), %rax
incq %rax
testl %ebx, %ebx
movq %rax, %rbx
movq 0x10(%rsp), %rbp
movq 0x29551(%rip), %rdi     # 0x35fb8
leaq 0x18d63(%rip), %rsi     # 0x257d1
je 0xc6df
jmp 0xcabb
movq 0x60(%rsp), %rdi
callq 0x7657
movl $0x0, 0xc(%rsp)
jmp 0xcabb
leaq 0x130(%rsp), %rdi
callq 0xbf2a
leaq 0x2b8(%rsp), %rdi
callq 0x6dea
leaq 0xb8(%rsp), %rdi
callq 0xbfa8
leaq 0x20(%rsp), %rdi
callq 0x911e
movl 0xc(%rsp), %eax
addq $0x558, %rsp            # imm = 0x558
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0xf0(%rsp), %rdi
callq 0x5778
jmp 0xcae6
movq %rax, %rbx
leaq 0x130(%rsp), %rdi
callq 0xbf2a
jmp 0xcb59
movq %rax, %rbx
jmp 0xcb66
movq %rax, %rbx
jmp 0xcb73
jmp 0xcb08
movq %rax, %rbx
jmp 0xcb35
jmp 0xcb0d
movq %rax, %rbx
jmp 0xcb59
movq %rax, %rbx
jmp 0xcb42
jmp 0xcb14
movq %rax, %rbx
jmp 0xcb2b
jmp 0xcb1b
movq %rax, %rbx
leaq 0x110(%rsp), %rdi
callq 0x5778
leaq 0x78(%rsp), %rdi
callq 0x5778
leaq 0x130(%rsp), %rdi
callq 0x5320
leaq 0x40(%rsp), %rdi
callq 0x5778
leaq 0x98(%rsp), %rdi
callq 0x5778
leaq 0x2b8(%rsp), %rdi
callq 0x6dea
leaq 0xb8(%rsp), %rdi
callq 0xbfa8
leaq 0x20(%rsp), %rdi
callq 0x911e
movq %rbx, %rdi
callq 0x56c0