// File: giovannarosone[P]BCR_LCP_GSA/TransposeFasta.cpp
// Function: TransposeFasta::findLengthNseq(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
bool TransposeFasta::findLengthNseq( const string& input, const string& fileOutput, string BCRprefPrev){
	//#if BCR_FROMCYC==1
	for (dataTypedimAlpha z = 0 ; z < SIZE_ALPHA-1; z++)
		freq[z]=0;
	freq[SIZE_ALPHA-1]=0;
	freq[(unsigned int)(TERMINATE_CHAR)]=1;
	//#endif

	//lengthRead = CYCLENUM;
    
	char *fileLen = new char[fileOutput.length()+10];
	sprintf(fileLen, "%s.len", fileOutput.c_str());
	
	

	string bufChar;
	
	bool lenSeq = false;
   	vector <dataTypelenSeq> lengthSeqVector;

	//Find max length and number of reads
	dataTypelenSeq charsNumber=0;
	lengthRead=0;
	nSeq = 0;
	lengthTexts = 0;       //Total length of all texts without $-symbols
	
	#if KSEQ_PARSER==0
	
		std::ifstream infile(input.c_str());
		
		if (infile.is_open() == false) {
			std::cerr << "TransposeFasta::findLengthNseq: could not open file \"" << input.c_str() << "\"!"<< std::endl;	
			exit (EXIT_FAILURE);
		}
		while (getline(infile, bufChar))  {
			if ( (bufChar.length() > 0) && ((bufChar[bufChar.length()-2] == '\r') || (bufChar[bufChar.length()-2] == '\n')) )
				bufChar[bufChar.length()-2] = '\0';
			else if ( (bufChar.length() > 0) && ((bufChar[bufChar.length()-1] == '\r') || (bufChar[bufChar.length()-1] == '\n')) )
				bufChar[bufChar.length()-1] = '\0';
			
			
			//std::cerr << "Nuova lettura: seq:" << bufChar << ". Length " << bufChar.length() << " the last char is "<< (char)bufChar[bufChar.length()-1] << std::endl;
					
			if( bufChar[0] == '>' ) {     //it is the title of fasta file
				nSeq++;
				//std::cerr << "--Length Sequence N. " << (int)(nSeq) << " is " << (int)charsNumber << std::endl;
				if (charsNumber != 0) {
					//charsNumber--;
					if (lengthRead != charsNumber) {
						if (lengthRead < charsNumber)
							lengthRead = charsNumber;
						if (nSeq > 2)
							lenSeq = true;
					}
					
					//dataTypeNSeq numchar = fwrite (&charsNumber, sizeof(dataTypelenSeq), 1 , OutFileLen);
					//assert( numchar == 1); // we should always read the same number of characters
					lengthSeqVector.push_back (charsNumber);
					lengthTexts += charsNumber;
					//if ((verboseEncode==1) || (verboseDistance ==1))
						//std::cerr << "Length Sequence N. " << (int)(nSeq-1) << " is " << (int)charsNumber << " nSeq= "<< nSeq << std::endl;
				}
									
				charsNumber = 0;
			}
			else   //no title
			{

				#if BCR_FROMCYC==1
					for (dataTypelenSeq z = 0 ; z < bufChar.length(); z++)
						freq[(unsigned int)(bufChar[z])]=1;
				#endif

				// increase the counter of chars
				charsNumber = charsNumber + bufChar.length();
				//std::cerr << "Stessa sequenza --Length Sequence N. " << (int)(nSeq) << " is " << (int)charsNumber << std::endl;
			}
				
		}   //end-while
		//Update the max length of the reads
		if (lengthRead != charsNumber) {
			if (lengthRead < charsNumber)
				lengthRead = charsNumber;
			lenSeq = true;
		}
		lengthSeqVector.push_back (charsNumber);
		lengthTexts += charsNumber;
		infile.close();
	//charsNumber--;
	
	#else
		//kseq 2019-11-08
		gzFile fp;
		kseq_t *seq;
		//int l;
		//cout << input.c_str() << "\n";
		#if  STORE_TITLE_FASTQ == 1
		    char *fnAux = new char[fileOutput.length()+10];
		    sprintf (fnAux,"%s%s",fileOutput.c_str(),".title\0");
		    FILE* OutFile = fopen(fnAux, "wb");
		    if (OutFile==NULL) {
			std::cerr << "TransposeFasta: (title) Error opening " << fnAux << std::endl;
			exit (EXIT_FAILURE);
		    }
		#endif
	
		fp = gzopen(input.c_str(), "r");
		seq = kseq_init(fp);
		while ((kseq_read(seq)) >= 0) {
			nSeq++;
			//printf("name: %s\n", seq->name.s);
			#if  STORE_TITLE_FASTQ == 1
                		fprintf(OutFile, "%s\n", seq->name.s);
            		#endif
			//if (seq->comment.l) 
				//printf("comment: %s\n", seq->comment.s);
			
			//printf("seq: %s\n", seq->seq.s);
			
			charsNumber = strlen(seq->seq.s);
			if (lengthRead != charsNumber) {
				if (lengthRead < charsNumber)
					lengthRead = charsNumber;
				if (nSeq > 2)
					lenSeq = true;
			}
			lengthSeqVector.push_back (charsNumber);
			lengthTexts += charsNumber;
					
			//if (seq->qual.l) 
			//	printf("qual: %s\n", seq->qual.s);
		} //end-while
	
		#if  STORE_TITLE_FASTQ == 1
            		fclose(OutFile);
        	#endif
	
		kseq_destroy(seq);
		gzclose(fp);
	#endif
	
	
	#if verboseEncode==1
	   	dataTypeNChar sum=0;
		for (dataTypeNSeq m=0; m < lengthSeqVector.size(); m++) {
           		sum += lengthSeqVector[m];
       }
	#endif


	if (lenSeq == true)
		cerr << "The  (new and-or old) reads have a different length." << endl;
	else
        cerr << "The (new and-or old) reads have the same length." << endl;

	static FILE *OutFileLen;                  // output file of the end positions;
	OutFileLen = fopen(fileLen, "wb");
	if (OutFileLen==NULL) {
			std::cerr << "TransposeFasta::findLengthNseq: could not open file \"" << fileLen << "\"!"<< std::endl;
			exit (EXIT_FAILURE);
	}

	//Store vector in file
	dataTypeNSeq numchar = fwrite (&lengthSeqVector[0], sizeof(dataTypelenSeq), lengthSeqVector.size(), OutFileLen);
	
//	std::cerr << "lengthTexts= " << (lengthTexts) << " lengthRead= " << (int)lengthRead << std::endl;
//	std::cerr << "lengthSeqVector.size= " << (lengthSeqVector.size()) << " nSeq= " << nSeq << std::endl;
	assert (lengthSeqVector.size() == numchar);
	assert (lengthSeqVector.size() == nSeq);
	
	lengthSeqVector.clear();
	//lengthSeqVector.shrink_to_fit();
			
	#if ( (BUILD_BCR_FROM_BCRpartials==1) && (STORE_LENGTH_IN_FILE==1)  )   //We have to add the length of the sequences from BCR partial files
		char *fnOutLenOld = new char[BCRprefPrev.length()+100];
		sprintf(fnOutLenOld, "%s.len", BCRprefPrev.c_str());
		FILE* OutFileLenOld = fopen(fnOutLenOld, "rb");
		if (OutFileLenOld==NULL) {
			std::cerr << "TransposeFasta::findLengthNseq (BUILD_BCR_FROM_BCRpartials): Error " << fnOutLenOld << "\n";
			exit (EXIT_FAILURE);
		}
		numchar =0;
		dataTypeNChar p;
		numchar = fread (&p, sizeof(dataTypelenSeq), 1 , OutFileLenOld);
		if (numchar > 0) {
			fwrite (&p, sizeof(dataTypelenSeq), numchar , OutFileLen);
			nAddedTextEGSA_transp=1;
		}
		while (numchar != 0) {
			numchar = fread (&p, sizeof(dataTypelenSeq), 1 , OutFileLenOld);
			if (numchar > 0) {
				fwrite (&p, sizeof(dataTypelenSeq), numchar , OutFileLen);
				nAddedTextEGSA_transp++;
			}
		}
		delete [] fnOutLenOld;
		fclose(OutFileLenOld);
	#endif

	delete [] fileLen;
	fclose(OutFileLen);
	
	cerr << "Number of sequences reading/writing: " << nSeq << "\n";
	cerr << "Number of characters reading/writing: " << lengthTexts << "\n";
	
	return true;
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x130(%rsp)
movq %rsi, 0x128(%rsp)
movq %rdx, 0x120(%rsp)
movq %rcx, 0x118(%rsp)
movq 0x130(%rsp), %rax
movq %rax, 0x98(%rsp)
movb $0x0, 0x117(%rsp)
movzbl 0x117(%rsp), %eax
cmpl $0xff, %eax
jge 0xf0f9
movq 0x98(%rsp), %rax
movzbl 0x117(%rsp), %ecx
movq $0x0, 0x18(%rax,%rcx,8)
movb 0x117(%rsp), %al
addb $0x1, %al
movb %al, 0x117(%rsp)
jmp 0xf0bf
movq 0x98(%rsp), %rax
movq $0x0, 0x810(%rax)
movq $0x1, 0x138(%rax)
movq 0x120(%rsp), %rdi
callq 0x33d0
movq %rax, %rdi
addq $0xa, %rdi
callq 0x3040
movq %rax, 0x108(%rsp)
movq 0x108(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x120(%rsp), %rdi
callq 0x3100
movq 0x88(%rsp), %rdi
movq %rax, %rdx
leaq 0xa051(%rip), %rsi      # 0x191b8
xorl %eax, %eax
callq 0x3060
leaq 0xe8(%rsp), %rdi
callq 0x3380
movb $0x0, 0xe7(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x12aa0
movq 0x98(%rsp), %rax
movb $0x0, 0xc7(%rsp)
movb $0x0, (%rax)
movl $0x0, 0x10(%rax)
movq $0x0, 0x8(%rax)
movq 0x128(%rsp), %rdi
callq 0x3100
movq %rax, %rdi
leaq 0xa0b5(%rip), %rsi      # 0x1927e
callq 0x33b0
movq %rax, 0x90(%rsp)
jmp 0xf1d8
movq 0x90(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rdi
callq 0xf610
movq %rax, 0x80(%rsp)
jmp 0xf1ff
movq 0x80(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rdi
callq 0xf650
movl %eax, 0x7c(%rsp)
jmp 0xf222
movl 0x7c(%rsp), %eax
cmpl $0x0, %eax
jl 0xf31b
movq 0x98(%rsp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
movq 0xb0(%rsp), %rax
movq 0x28(%rax), %rdi
callq 0x3120
movq %rax, %rcx
movq 0x98(%rsp), %rax
movb %cl, 0xc7(%rsp)
movzbl (%rax), %eax
movzbl 0xc7(%rsp), %ecx
cmpl %ecx, %eax
je 0xf2e7
movq 0x98(%rsp), %rax
movzbl (%rax), %eax
movzbl 0xc7(%rsp), %ecx
cmpl %ecx, %eax
jge 0xf2cf
movq 0x98(%rsp), %rax
movb 0xc7(%rsp), %cl
movb %cl, (%rax)
jmp 0xf2cf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa8(%rsp)
movl %eax, 0xa4(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x12b80
leaq 0xe8(%rsp), %rdi
callq 0x3180
jmp 0xf5fb
movq 0x98(%rsp), %rax
cmpl $0x2, 0x10(%rax)
jbe 0xf2e5
movb $0x1, 0xe7(%rsp)
jmp 0xf2e7
leaq 0xc8(%rsp), %rdi
leaq 0xc7(%rsp), %rsi
callq 0x12ab0
jmp 0xf2fe
movq 0x98(%rsp), %rax
movzbl 0xc7(%rsp), %ecx
addq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
jmp 0xf20f
movq 0xb0(%rsp), %rdi
callq 0xfa60
jmp 0xf32a
movq 0xb8(%rsp), %rdi
callq 0x3460
jmp 0xf339
movb 0xe7(%rsp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0xf379
movq 0x10c9f(%rip), %rdi     # 0x1fff0
leaq 0x9e67(%rip), %rsi      # 0x191bf
callq 0x3260
movq %rax, 0x70(%rsp)
jmp 0xf364
movq 0x70(%rsp), %rdi
movq 0x10c50(%rip), %rsi     # 0x1ffc0
callq 0x32a0
jmp 0xf377
jmp 0xf3a8
movq 0x10c70(%rip), %rdi     # 0x1fff0
leaq 0x9e6d(%rip), %rsi      # 0x191f4
callq 0x3260
movq %rax, 0x68(%rsp)
jmp 0xf393
movq 0x68(%rsp), %rdi
movq 0x10c21(%rip), %rsi     # 0x1ffc0
callq 0x32a0
jmp 0xf3a6
jmp 0xf3a8
movq 0x108(%rsp), %rdi
leaq 0x972a(%rip), %rsi      # 0x18ae1
callq 0x32e0
movq %rax, 0x60(%rsp)
jmp 0xf3c3
movq 0x60(%rsp), %rax
movq %rax, 0x10f89(%rip)     # 0x20358
cmpq $0x0, 0x10f81(%rip)     # 0x20358
jne 0xf441
movq 0x10c10(%rip), %rdi     # 0x1fff0
leaq 0x9e3e(%rip), %rsi      # 0x19225
callq 0x3260
movq %rax, 0x58(%rsp)
jmp 0xf3f3
movq 0x58(%rsp), %rdi
movq 0x108(%rsp), %rsi
callq 0x3260
movq %rax, 0x50(%rsp)
jmp 0xf40c
movq 0x50(%rsp), %rdi
leaq 0x9e43(%rip), %rsi      # 0x1925b
callq 0x3260
movq %rax, 0x48(%rsp)
jmp 0xf424
movq 0x48(%rsp), %rdi
movq 0x10b90(%rip), %rsi     # 0x1ffc0
callq 0x32a0
jmp 0xf437
movl $0x1, %edi
callq 0x3300
xorl %eax, %eax
movl %eax, %esi
leaq 0xc8(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x12b20
movq 0x30(%rsp), %rdi
movq %rax, 0x38(%rsp)
callq 0x12b40
movq 0x38(%rsp), %rdi
movq %rax, %rdx
movq 0x10ee3(%rip), %rcx     # 0x20358
movl $0x1, %esi
callq 0x3510
movq %rax, 0x40(%rsp)
jmp 0xf486
movq 0x40(%rsp), %rax
movl %eax, 0xa0(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x12b40
movl 0xa0(%rsp), %ecx
cmpq %rcx, %rax
jne 0xf4ad
jmp 0xf4cc
leaq 0x9daa(%rip), %rdi      # 0x1925e
leaq 0x9dc5(%rip), %rsi      # 0x19280
movl $0xea, %edx
leaq 0x9dcc(%rip), %rcx      # 0x19293
callq 0x3190
leaq 0xc8(%rsp), %rdi
callq 0x12b40
movq 0x98(%rsp), %rcx
movl 0x10(%rcx), %ecx
cmpq %rcx, %rax
jne 0xf4eb
jmp 0xf50a
leaq 0x9ded(%rip), %rdi      # 0x192df
leaq 0x9d87(%rip), %rsi      # 0x19280
movl $0xeb, %edx
leaq 0x9d8e(%rip), %rcx      # 0x19293
callq 0x3190
leaq 0xc8(%rsp), %rdi
callq 0x12b60
movq 0x108(%rsp), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0xf534
movq 0x28(%rsp), %rdi
callq 0x3330
movq 0x10e1d(%rip), %rdi     # 0x20358
callq 0x3270
jmp 0xf542
movq 0x10aa7(%rip), %rdi     # 0x1fff0
leaq 0x9dae(%rip), %rsi      # 0x192fe
callq 0x3260
movq %rax, 0x20(%rsp)
jmp 0xf55c
movq 0x20(%rsp), %rdi
movq 0x98(%rsp), %rax
movl 0x10(%rax), %esi
callq 0x3350
movq %rax, 0x18(%rsp)
jmp 0xf578
movq 0x18(%rsp), %rdi
leaq 0x95cc(%rip), %rsi      # 0x18b50
callq 0x3260
jmp 0xf58b
movq 0x10a5e(%rip), %rdi     # 0x1fff0
leaq 0x9d8b(%rip), %rsi      # 0x19324
callq 0x3260
movq %rax, 0x10(%rsp)
jmp 0xf5a5
movq 0x10(%rsp), %rdi
movq 0x98(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0x3090
movq %rax, 0x8(%rsp)
jmp 0xf5c2
movq 0x8(%rsp), %rdi
leaq 0x9582(%rip), %rsi      # 0x18b50
callq 0x3260
jmp 0xf5d5
leaq 0xc8(%rsp), %rdi
callq 0x12b80
leaq 0xe8(%rsp), %rdi
callq 0x3180
movb $0x1, %al
andb $0x1, %al
addq $0x138, %rsp            # imm = 0x138
retq
movq 0xa8(%rsp), %rdi
callq 0x34a0
nopl (%rax,%rax)