// File: /workspace/github_cpp_makefile_star2_O1/giovannarosone[P]BCR_LCP_GSA/BCRexternalBWT.cpp
// Function: BCRexternalBWT::storeEntireBWTFilePartial(char const*)
void BCRexternalBWT::storeEntireBWTFilePartial( const char* fn ) {

	static FILE *OutFileBWT, *InFileBWT;                  // output and input file BWT;
	char *filenameIn = new char[strlen(fn)+100];
	char *filename = new char[strlen(fn)+100];
	
	#if USE_QS == 1
		static FILE *OutFileBWTQS, *InFileBWTQS;                  // output and input file BWT;
		char *filenameInQS = new char[120];
		char *filenameQS = new char[120];
		char *fnQS = new char[strlen(fn)+100];
		sprintf (fnQS,"%s%s",fn,".ebwt.qs");
	#endif
	
	dataTypeNChar numchar=0;
	dataTypeNChar numcharWrite=0;

	uchar *buffer = new uchar[SIZEBUFFER];
	std::cerr << "storeEntireBWTFilePartial:SIZEBUFFER is " << SIZEBUFFER << std::endl;

	dataTypeNChar *freqOut = new dataTypeNChar [SIZE_ALPHA];
	for (dataTypedimAlpha i = 0; i < SIZE_ALPHA-1; ++i)
        freqOut[i] = 0;
	freqOut[SIZE_ALPHA-1] = 0;

	char *fnBWT = new char[strlen(fn)+100];
	numchar=sprintf (fnBWT,"%s%s",fn,".ebwt");		
	OutFileBWT = fopen(fnBWT, "wb");
	if (OutFileBWT==NULL) {
		std::cerr << "storeEntireBWTFilePartial: Entire BWT file: Error opening " << std::endl;
		exit (EXIT_FAILURE);
	}
	
	#if USE_QS == 1
		OutFileBWTQS = fopen(fnQS, "wb");
		if (OutFileBWTQS==NULL) {
			std::cerr << "storeEntireBWTFilePartial: Entire BWT QS file: Error opening " << std::endl;
			exit (EXIT_FAILURE);
		}
	#endif

	std::cerr << "storeEntireBWTFilePartial: Build the entire BWT file and compute the distribution of chars.\n";

	for (dataTypedimAlpha g = 0 ; g < sizeAlpha; g++) {
		numchar=sprintf (filename, "bwt_%d", g);
		numchar=sprintf (filenameIn,"%s%s",filename,ext);
		InFileBWT = fopen(filenameIn, "rb");
		if (InFileBWT==NULL) {
			std::cerr << "storeEntireBWTFilePartial: BWT file " << (unsigned int)g <<": Error opening " << std::endl;
			exit (EXIT_FAILURE);
		}

		#if USE_QS == 1
			numchar=sprintf (filenameQS, "bwt.qs_%d", g);
			numchar=sprintf (filenameInQS,"%s%s",filenameQS,ext);
			InFileBWTQS = fopen(filenameInQS, "rb");
			if (InFileBWTQS==NULL) {
				std::cerr << "storeEntireBWTFilePartial: BWT QS file " << (unsigned int)g <<": Error opening " << std::endl;
				exit (EXIT_FAILURE);
			}
		#endif

		//std::cerr << "BWT file " << (unsigned int)g << "= ";
		numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,InFileBWT);
		numcharWrite = fwrite (buffer, sizeof(uchar), numchar , OutFileBWT);
		//std::cerr << "numchar= " << numchar << std::endl;
		//std::cerr << "numcharWrite= " << numcharWrite << std::endl;
		assert(numchar == numcharWrite); // we should always read/write the same number of characters

		for (dataTypeNChar j = 0 ; j < numchar; j++)
	        freqOut[(unsigned int)(buffer[j])]++;

		#if USE_QS == 1
			numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,InFileBWTQS);
			numcharWrite = fwrite (buffer, sizeof(uchar), numchar , OutFileBWTQS);
			assert(numchar == numcharWrite);
		#endif

		while (numchar!=0) {
			numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,InFileBWT);
			numcharWrite = fwrite (buffer, sizeof(uchar), numchar , OutFileBWT);
			assert(numchar == numcharWrite); // we should always read/write the same number of characters

			for (dataTypeNChar j = 0 ; j < numchar; j++)
				freqOut[(unsigned int)(buffer[j])]++;
			
			#if USE_QS == 1
				numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,InFileBWTQS);
				numcharWrite = fwrite (buffer, sizeof(uchar), numchar , OutFileBWTQS);
				assert(numchar == numcharWrite);
			#endif

		}

		fclose(InFileBWT);		
		#if USE_QS==1
			fclose(InFileBWTQS);
		#endif
			
	}
	fclose(OutFileBWT);

	#if verboseEncode==1
		std::cerr << "\nThe Entire BWT:"<< std::endl;
		fnBWT = new char[strlen(fn) + 7];
		sprintf (fnBWT,"%s%s",fn,".ebwt");
		OutFileBWT = fopen(fnBWT, "rb");
		if (OutFileBWT==NULL) {
			std::cerr << "storeEntireBWTFilePartial: Entire BWT file: Error opening " << std::endl;
			exit (EXIT_FAILURE);
		}

		numchar = 1;
		for (dataTypeNSeq g = 0 ; g < SIZEBUFFER; g++)
			buffer[g] = '\0';
		numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,OutFileBWT);
   		if (numchar==0)
			   std::cerr  << "empty\n";
		else
			    std::cerr  << buffer;
       	while (numchar!=0) {
	     		for (dataTypeNChar g = 0 ; g < SIZEBUFFER; g++)
		     		buffer[g] = '\0';
			   numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,OutFileBWT);
			   if (numchar!=0)
			      std::cerr  << buffer;
        }
		std::cerr << std::endl;
		fclose(OutFileBWT);
	#endif

	delete [] buffer;

	
	
	int check=0;
	std::cerr << "Distribution in BWT\n";
	for (dataTypedimAlpha g = 0 ; g < SIZE_ALPHA-1; g++) {
		if (freqOut[g] > 0){
			InFileBWT = openFilePartialIn(alpha[(unsigned int)g]);
			fseek(InFileBWT,0,SEEK_END);
			dataTypeNChar lengthBWTPartial=ftell(InFileBWT);
			if (freqOut[g] == lengthBWTPartial)
				std::cerr << (unsigned int)g << " freq: " << freqOut[g] << "\n";
			else {
				std::cerr << (unsigned int)g << " freq: " << freqOut[g] << " freq in BWT: " << lengthBWTPartial << "***********************\n";
				check = 1;
			}
			closeFilePartial(InFileBWT);
			
			#if deletePartialBWT == 1
				sprintf (filename, "bwt_%d", alpha[(unsigned int)g]);
				sprintf (filenameIn,"%s%s",filename,ext);
				if (remove(filenameIn)!=0)
					std::cerr << "storeEntireBWTFilePartial: Error deleting (bwt aux): " << filenameIn << std::endl;
			#endif
			
			#if ((deletePartialQS == 1) && (USE_QS==1))
				sprintf (filename, "bwt.qs_%d", alpha[(unsigned int)g]);
				sprintf (filenameInQS,"%s%s",filename,ext);
				if (remove(filenameInQS)!=0)
					std::cerr << "storeEntireBWTFilePartial: Error deleting (qs aux): " << filenameInQS << std::endl;
			#endif
			
		}
	}
	if (freqOut[(SIZE_ALPHA-1)] > 0){
		InFileBWT = openFilePartialIn(alpha[(unsigned int)(SIZE_ALPHA-1)]);
		fseek(InFileBWT,0,SEEK_END);
		dataTypeNChar lengthBWTPartial=ftell(InFileBWT);
		if (freqOut[(SIZE_ALPHA-1)] == lengthBWTPartial)
			std::cerr << (unsigned int)(SIZE_ALPHA-1) << " freq: " << freqOut[(SIZE_ALPHA-1)] << "\n";
		else {
			std::cerr << (unsigned int)(SIZE_ALPHA-1) << " freq: " << freqOut[(SIZE_ALPHA-1)] << " freq in BWT: " << lengthBWTPartial << "***********************\n";
			check = 1;
		}
		closeFilePartial(InFileBWT);
		#if deletePartialBWT == 1
			sprintf (filename, "bwt_%d", alpha[(unsigned int)(SIZE_ALPHA-1)] );
			sprintf (filenameIn,"%s%s",filename,ext);
			if (remove(filenameIn)!=0)
				std::cerr << "storeEntireBWTFilePartial: Error deleting (bwt aux): " << filenameIn << std::endl;
		#endif
		
		#if ((deletePartialQS == 1) && (USE_QS==1))
			sprintf (filename, "bwt.qs_%d", alpha[(unsigned int)SIZE_ALPHA-1]);
			sprintf (filenameInQS,"%s%s",filename,ext);
			if (remove(filenameInQS)!=0)
				std::cerr << "storeEntireBWTFilePartial: Error deleting (qs aux): " << filenameInQS << std::endl;
		#endif
		
	}

	if (check == 1) {
		std::cerr << "storeEntireBWTFilePartial: WARNING! Some length partial BWT != the number of occorrences! " << std::endl;
		exit (EXIT_FAILURE);
	}
	else
		std::cerr << "storeEntireBWTFilePartial: test ok! " << std::endl;

	delete [] freqOut;
	delete [] filenameIn;
	delete [] filename;

	#if USE_QS == 1
		delete [] filenameInQS;
		delete [] filenameQS;
		delete [] fnQS;
	#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r13
movq %rdi, %r12
movq %rsi, %rdi
callq 0x3120
leaq 0x64(%rax), %r14
movq %r14, %rdi
callq 0x3040
movq %rax, %rbx
movq %r14, %rdi
callq 0x3040
movq %rax, 0x10(%rsp)
movl $0x400, %edi            # imm = 0x400
callq 0x3040
movq %rax, %rbp
movq 0xaef6(%rip), %r14      # 0x10ff0
leaq 0x6b56(%rip), %rsi      # 0xcc57
movl $0x28, %edx
movq %r14, %rdi
callq 0x32d0
movq %r14, %rdi
movl $0x400, %esi            # imm = 0x400
callq 0x3440
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %r14, %rdi
callq 0x3050
movq %rax, %rdi
callq 0x31e0
movl $0x800, %edi            # imm = 0x800
callq 0x3040
movq %rax, %r15
movl $0x7f8, %edx            # imm = 0x7F8
movq %rax, %rdi
xorl %esi, %esi
callq 0x3170
movq $0x0, 0x7f8(%r15)
movq %r13, %rdi
callq 0x3120
leaq 0x64(%rax), %rdi
callq 0x3040
movq %rax, %r14
leaq 0x697d(%rip), %rsi      # 0xcb04
leaq 0x6a67(%rip), %rcx      # 0xcbf5
movq %rax, %rdi
movq %r13, %rdx
xorl %eax, %eax
callq 0x3070
leaq 0x6967(%rip), %rsi      # 0xcb09
movq %r14, %rdi
callq 0x32e0
movq %rax, 0xb117(%rip)      # 0x112c8
movq 0xae38(%rip), %rdi      # 0x10ff0
testq %rax, %rax
je 0x675c
leaq 0x6af3(%rip), %rsi      # 0xccbb
movl $0x5c, %edx
callq 0x32d0
cmpb $0x0, 0x148(%r12)
je 0x62fe
xorl %r13d, %r13d
movq 0x10(%rsp), %r14
movq %r14, %rdi
leaq 0x6dd5(%rip), %rsi      # 0xcfc8
movl %r13d, %edx
xorl %eax, %eax
callq 0x3070
movq %rbx, %rdi
leaq 0x68fd(%rip), %rsi      # 0xcb04
movq %r14, %rdx
leaq 0x6846(%rip), %rcx      # 0xca57
xorl %eax, %eax
callq 0x3070
movq %rbx, %rdi
leaq 0x6731(%rip), %rsi      # 0xc953
callq 0x32e0
movq %rax, 0xb0a2(%rip)      # 0x112d0
testq %rax, %rax
je 0x66fe
movl $0x1, %esi
movl $0x400, %edx            # imm = 0x400
movq %rbp, %rdi
movq %rax, %rcx
callq 0x3390
movq %rax, %r14
movq 0xb072(%rip), %rcx      # 0x112c8
movl $0x1, %esi
movq %rbp, %rdi
movq %rax, %rdx
callq 0x34c0
cmpq %rax, %r14
jne 0x673d
testq %r14, %r14
je 0x62dd
xorl %eax, %eax
movzbl (%rbp,%rax), %ecx
incq (%r15,%rcx,8)
incq %rax
cmpq %rax, %r14
jne 0x6276
jmp 0x629c
xorl %eax, %eax
movzbl (%rbp,%rax), %ecx
incq (%r15,%rcx,8)
incq %rax
cmpq %rax, %r14
jne 0x628b
movq 0xb02d(%rip), %rcx      # 0x112d0
movl $0x1, %esi
movl $0x400, %edx            # imm = 0x400
movq %rbp, %rdi
callq 0x3390
movq %rax, %r14
movq 0xb009(%rip), %rcx      # 0x112c8
movl $0x1, %esi
movq %rbp, %rdi
movq %rax, %rdx
callq 0x34c0
cmpq %rax, %r14
jne 0x66df
testq %r14, %r14
jne 0x6289
movq 0xafec(%rip), %rdi      # 0x112d0
callq 0x32a0
incl %r13d
movzbl 0x148(%r12), %eax
cmpl %eax, %r13d
jb 0x61e4
movq 0xafc3(%rip), %rdi      # 0x112c8
callq 0x32a0
movq %rbp, %rdi
callq 0x3330
leaq 0x6a69(%rip), %rsi      # 0xcd82
movl $0x14, %edx
movq 0xaccb(%rip), %rdi      # 0x10ff0
callq 0x32d0
xorl %ebp, %ebp
movl $0x0, 0x4(%rsp)
movq %rbx, 0x8(%rsp)
cmpq $0x0, (%r15,%rbp,8)
je 0x64bc
movzbl 0x48(%r12,%rbp), %esi
movq (%r12), %rax
movq %r12, %rdi
callq *0x70(%rax)
movq %rax, 0xaf75(%rip)      # 0x112d0
movq %rax, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x32c0
movq 0xaf5f(%rip), %rdi      # 0x112d0
callq 0x3030
movq %rax, %r14
movq (%r15,%rbp,8), %rbx
movq 0xac6c(%rip), %rdi      # 0x10ff0
movq %rbp, %rsi
callq 0x31d0
movq %rax, %r13
movl $0x7, %edx
movq %rax, %rdi
leaq 0x69f9(%rip), %rsi      # 0xcd97
callq 0x32d0
movq (%r15,%rbp,8), %rsi
movq %r13, %rdi
callq 0x31d0
movq %rax, %r13
cmpq %r14, %rbx
jne 0x63cd
movl $0x1, %edx
movq %r13, %rdi
leaq 0x6670(%rip), %rsi      # 0xca36
callq 0x32d0
jmp 0x6408
movl $0xe, %edx
movq %r13, %rdi
leaq 0x69c3(%rip), %rsi      # 0xcd9f
callq 0x32d0
movq %r13, %rdi
movq %r14, %rsi
callq 0x31d0
movl $0x18, %edx
movq %rax, %rdi
leaq 0x69b3(%rip), %rsi      # 0xcdae
callq 0x32d0
movl $0x1, 0x4(%rsp)
movq 0x8(%rsp), %rbx
movq 0xaebc(%rip), %rsi      # 0x112d0
movq (%r12), %rax
movq %r12, %rdi
callq *0x80(%rax)
movzbl 0x48(%r12,%rbp), %edx
movq 0x10(%rsp), %r14
movq %r14, %rdi
leaq 0x6b92(%rip), %rsi      # 0xcfc8
xorl %eax, %eax
callq 0x3070
movq %rbx, %rdi
leaq 0x66bd(%rip), %rsi      # 0xcb04
movq %r14, %rdx
leaq 0x6606(%rip), %rcx      # 0xca57
xorl %eax, %eax
callq 0x3070
movq %rbx, %rdi
callq 0x3480
testl %eax, %eax
je 0x64bc
movl $0x35, %edx
movq 0xab80(%rip), %r14      # 0x10ff0
movq %r14, %rdi
leaq 0x694d(%rip), %rsi      # 0xcdc7
callq 0x32d0
movq %rbx, %rdi
callq 0x3120
movq %r14, %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x32d0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %r14, %rdi
callq 0x3050
movq %rax, %rdi
callq 0x31e0
incq %rbp
cmpq $0xff, %rbp
jne 0x6339
cmpq $0x0, 0x7f8(%r15)
je 0x657a
movzbl 0x147(%r12), %esi
movq (%r12), %rax
movq %r12, %rdi
callq *0x70(%rax)
movq %rax, 0xaddc(%rip)      # 0x112d0
movq %rax, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x32c0
movq 0xadc6(%rip), %rdi      # 0x112d0
callq 0x3030
movq %rax, %r14
movq 0x7f8(%r15), %rbx
movq 0xaad0(%rip), %r13      # 0x10ff0
movl $0xff, %esi
movq %r13, %rdi
callq 0x31d0
movq %rax, %rbp
leaq 0x6860(%rip), %rsi      # 0xcd97
movl $0x7, %edx
movq %rax, %rdi
callq 0x32d0
movq 0x7f8(%r15), %rsi
movq %rbp, %rdi
callq 0x31d0
movq %rax, %rbp
cmpq %r14, %rbx
jne 0x6583
leaq 0x64d4(%rip), %rsi      # 0xca36
movl $0x1, %edx
movq %rbp, %rdi
callq 0x32d0
movq 0x8(%rsp), %rbx
movl 0x4(%rsp), %ebp
jmp 0x65c0
movl 0x4(%rsp), %ebp
jmp 0x666c
leaq 0x6815(%rip), %rsi      # 0xcd9f
movl $0xe, %edx
movq %rbp, %rdi
callq 0x32d0
movq %rbp, %rdi
movq %r14, %rsi
callq 0x31d0
leaq 0x6805(%rip), %rsi      # 0xcdae
movl $0x18, %edx
movq %rax, %rdi
callq 0x32d0
movl $0x1, %ebp
movq 0x8(%rsp), %rbx
movq 0xad09(%rip), %rsi      # 0x112d0
movq (%r12), %rax
movq %r12, %rdi
callq *0x80(%rax)
movzbl 0x147(%r12), %edx
leaq 0x69e4(%rip), %rsi      # 0xcfc8
movq 0x10(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x3070
leaq 0x650a(%rip), %rsi      # 0xcb04
leaq 0x6456(%rip), %rcx      # 0xca57
movq %rbx, %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3070
movq %rbx, %rdi
callq 0x3480
testl %eax, %eax
je 0x666c
leaq 0x67a6(%rip), %rsi      # 0xcdc7
movl $0x35, %edx
movq %r13, %rdi
callq 0x32d0
movq %rbx, %rdi
callq 0x3120
movq %r13, %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x32d0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %r13, %rdi
callq 0x3050
movq %rax, %rdi
callq 0x31e0
cmpl $0x1, %ebp
je 0x6765
leaq 0x67dc(%rip), %rsi      # 0xce58
movl $0x24, %edx
movq 0xa968(%rip), %r14      # 0x10ff0
movq %r14, %rdi
callq 0x32d0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %r14, %rdi
callq 0x3050
movq %rax, %rdi
callq 0x31e0
movq %r15, %rdi
callq 0x3330
movq %rbx, %rdi
callq 0x3330
movq 0x10(%rsp), %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3330
leaq 0x6494(%rip), %rdi      # 0xcb7a
leaq 0x5cf0(%rip), %rsi      # 0xc3dd
leaq 0x6649(%rip), %rcx      # 0xcd3d
movl $0x1392, %edx           # imm = 0x1392
callq 0x31a0
movq 0xa8eb(%rip), %rdi      # 0x10ff0
leaq 0x660c(%rip), %rsi      # 0xcd18
callq 0x3290
movq %rax, %rdi
movl %r13d, %esi
callq 0x3350
leaq 0x623c(%rip), %rsi      # 0xc95f
movq %rax, %rdi
callq 0x3290
movq %rax, %rdi
callq 0x3140
movl $0x1, %edi
callq 0x3300
leaq 0x6436(%rip), %rdi      # 0xcb7a
leaq 0x5c92(%rip), %rsi      # 0xc3dd
leaq 0x65eb(%rip), %rcx      # 0xcd3d
movl $0x1384, %edx           # imm = 0x1384
callq 0x31a0
leaq 0x651d(%rip), %rsi      # 0xcc80
jmp 0x6726
movq 0xa884(%rip), %rdi      # 0x10ff0
leaq 0x668a(%rip), %rsi      # 0xcdfd
jmp 0x6726
nop