// File: /workspace/github_cpp_makefile_star2_O2/lrq3000[P]rfrb/./src/raidSystem.cpp
// Function: RaidSystem::easyCheck()
bool RaidSystem::easyCheck()
{
	//Initial buffer allocations
	char buf1[CHECKSIZE];
	char buf5[CHECKSIZE];
	char *checkAgainstMe;
	char *in;
	unsigned int raid1=0, raid5=0, misses=0;

	//Starting fileReader for each image
	std::vector<FileReader *> inFiles = handle->getInFiles();

	//Check if enough images are specified
	if(inFiles.size() < 2)
	{
		std::cout << "\tThere are too few devices for a Raid system." << std::endl;
		return false;
	}
	//Check if images are too broken
	if (handle->findGoodBlock() == false)
	{
		std::cerr << "\tNo valid readable block found! Disc too broken!" << std::endl;
		return false;
	}

	for (int j = 0; j < CHECKSIZE; ++j)
	{
		buf1[j] = 0;
	}

	std::cout << "\tTesting 1.5 million blocks to check if a valid Raid-version can be estimated." << std::endl;

	//Iterate over many blocks and trying to estimate the RAID-level
	for (size_t i = 0; i < inFiles.size(); ++i)
	{
		inFiles.at(i)->setBlockSize(CHECKSIZE);
	}
	std::cout << "| ";
	for (size_t count=0; count < 1500000; ++count)
	{
		if ((count%5000) == 0)
			std::cout << "* ";
		//Get a block from the first image
		checkAgainstMe = inFiles.at(0)->getBlock();
		int raid1_miss = 0;
		int raid1_hit = 0;
		for (int j = 0; j < CHECKSIZE; ++j)
		{
			buf5[j] = checkAgainstMe[j];
		}
		//Get blocks from the other images
		for (unsigned int j = 1; j < inFiles.size(); ++j)
		{
			in = inFiles.at(j)->getBlock();
			//Calculate XOR
			for (int x = 0; x < CHECKSIZE; ++x)
			{
				buf1[x] = checkAgainstMe[x]^in[x];
				buf5[x] = buf5[x]^in[x];
			}
			//If XOR is in buf1 is not zero, then we have no RAID1
			if (checkForNull(buf1, CHECKSIZE)==false)
			{
				++raid1_miss;
				for (int x = 0; x < CHECKSIZE; ++x)
				{
					buf1[x] = 0;
				}
			}
			else
			{
				++raid1_hit;
			}
		}
		if (raid1_miss == 0)
		{
			//Blocks are equal, we have a RAID1 hit
			++raid1;
		}
		//else if (checkForEqual(buf5,checkAgainstMe+startAdress,CHECKSIZE) == true)
		else if (checkForNull(buf5, CHECKSIZE)==true)
		{
			//block0 = block1 XOR block2 XOR ...
			//There is Parity information, that's why we assume RAID5
			++raid5;
		}
		else
		{
			++misses;
		}
		if (handle->findGoodBlock() == false)
		{
			std::cout << "\tCouldnt find enough testable blocks. Trying to estimate with heuristics." << std::endl;
			break;
		}
	}
	std::cout << std::endl;

	//Final outputs
	std::cout << "\tMirrored blocks:\t\t: " << std::setw(6) << raid1 << "\t(Raid1)"<< std::endl;
	std::cout << "\tBlocks with parity info\t\t: " << std::setw(6) << raid5 << "\t(Raid5)"<< std::endl;
	std::cout << "\tBlocks without relevant info\t: "       << std::setw(6) << misses << std::endl;
	handle->reset();

	//Trying to estimate the RAID-level from the results above
	if (raid1 > (misses+raid5)*1.5)
	{
		//Enough RAID1 hits to evaluate this to RAID1
		raidSystem = Raid1;
		std::cout << "Found a Raid 1 system." << std::endl;
		return true;
	}
	else if (raid5 > (misses+raid1)*1.5 && inFiles.size() >= 3)
	{
		//Enough RAID5 hits and enough images to evaluate this to RAID5
		raidSystem = Raid5_complete;
		std::cout << "Found a complete Raid 5 system." << std::endl;
		return true;
	}

	//See if you can find two identical partitiontables at the beginning of two images out of all.
	std::vector<char *> tables;
	for (unsigned int i = 0; i < inFiles.size(); ++i)
	{
		char *buf = inFiles.at(i)->getBlock();
		if (checkForNull(buf, 512)==false)
			tables.push_back(buf);
	}
	//If this can be found, it's RAID5 with one missing image (incomplete).
	if (tables.size() == 2)
	{
		if (checkForEqual(tables.at(0),tables.at(1),512)==true)
		{
			lostImages = 1;
			raidSystem = Raid5_incomplete;
			std::cout << "Found a mirrored partition table. Has to be an incomplete Raid 5 system." << std::endl;
			handle->reset();
			return true;
		}
	}
	//Otherwise it can still be RAID5-incomplete or RAID0
	if (raid1 < (100*misses/(inFiles.size()+1)) && (raid1+raid5) > 0.007*(float)misses)
	{
		//At this point it could only be RAID0 or RAID5.
		//There are enough hits for identical blocks and parity blocks => RAID5
		lostImages = 1;
		raidSystem = Raid5_incomplete;
		std::cout << "Some mirrored blocks and some parity blocks found. It's probably an incomplete Raid 5 system." << std::endl;
		handle->reset();
		return true;
	}
	else if (raid1 >= (100*misses/(inFiles.size()+1)))
	{
		//Still too much identical blocks found. This has to be RAID1
		raidSystem = Raid1;
		std::cout << "Above average mirrored blocks found. Has to be a Raid 1 system." << std::endl;
		return true;
	}
	else
	{
		//Now it can only be RAID0
		raidSystem = Raid0;
		std::cout << "Too few mirrored blocks or parity infos found. Has to be a Raid 0 system." << std::endl;
		return true;
	}
	return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x478, %rsp            # imm = 0x478
movq %rdi, %rbx
movq (%rdi), %rdi
callq 0x7986
leaq 0x20(%rsp), %r14
movq %r14, %rdi
movq %rax, %rsi
callq 0x6ed4
movq 0x8(%r14), %rax
subq (%r14), %rax
cmpq $0x9, %rax
jae 0x61af
leaq 0xd3a0(%rip), %rsi      # 0x13546
movq 0x17e03(%rip), %rdi     # 0x1dfb0
jmp 0x61dd
movq (%rbx), %rdi
callq 0x7aac
testb %al, %al
je 0x61cf
xorl %eax, %eax
cmpq $0x200, %rax            # imm = 0x200
je 0x620a
movb $0x0, 0x70(%rsp,%rax)
incq %rax
jmp 0x61bd
leaq 0xd39e(%rip), %rsi      # 0x13574
movq 0x17e13(%rip), %rdi     # 0x1dff0
callq 0x5380
movq %rax, %rdi
callq 0x5180
xorl %ebx, %ebx
leaq 0x20(%rsp), %rdi
callq 0x714e
movl %ebx, %eax
addq $0x478, %rsp            # imm = 0x478
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x17d9f(%rip), %rdi     # 0x1dfb0
leaq 0xd38d(%rip), %rsi      # 0x135a5
callq 0x5380
movq %rax, %rdi
callq 0x5180
xorl %r14d, %r14d
leaq 0x20(%rsp), %r15
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
sarq $0x3, %rax
cmpq %rax, %r14
jae 0x625d
movq %r15, %rdi
movq %r14, %rsi
callq 0x6f22
movq (%rax), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0xf644
incq %r14
jmp 0x622d
movq 0x17d4c(%rip), %rdi     # 0x1dfb0
leaq 0xd389(%rip), %rsi      # 0x135f4
callq 0x5380
movq $0x0, 0x10(%rsp)
leaq 0x20(%rsp), %r12
leaq 0x70(%rsp), %r13
xorl %r14d, %r14d
movq $0x0, 0x8(%rsp)
movq $0x0, 0x18(%rsp)
movq %rbx, 0x38(%rsp)
cmpq $0x16e360, %r14         # imm = 0x16E360
je 0x63f6
movl %r14d, %eax
xorl %edx, %edx
movl $0x1388, %ecx           # imm = 0x1388
divl %ecx
testl %edx, %edx
jne 0x62cd
movq 0x17cef(%rip), %rdi     # 0x1dfb0
leaq 0xd32f(%rip), %rsi      # 0x135f7
callq 0x5380
movq %r12, %rdi
xorl %esi, %esi
callq 0x6f22
movq (%rax), %rdi
callq 0xf544
movq %rax, %r15
xorl %eax, %eax
cmpq $0x200, %rax            # imm = 0x200
je 0x62fc
movb (%r15,%rax), %cl
movb %cl, 0x270(%rsp,%rax)
incq %rax
jmp 0x62e4
xorl %ebx, %ebx
pushq $0x1
popq %rax
movl %eax, %ebp
movl %ebp, %ebp
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
sarq $0x3, %rax
cmpq %rbp, %rax
jbe 0x637c
movq %r12, %rdi
movq %rbp, %rsi
callq 0x6f22
movq (%rax), %rdi
callq 0xf544
xorl %ecx, %ecx
cmpq $0x200, %rcx            # imm = 0x200
je 0x6351
movb (%rax,%rcx), %dl
movb (%r15,%rcx), %sil
xorb %dl, %sil
movb %sil, 0x70(%rsp,%rcx)
xorb %dl, 0x270(%rsp,%rcx)
incq %rcx
jmp 0x632d
movl $0x200, %edx            # imm = 0x200
movq %r13, %rsi
callq 0x6e60
testb %al, %al
jne 0x6378
xorl %eax, %eax
cmpq $0x200, %rax            # imm = 0x200
je 0x6376
movb $0x0, 0x70(%rsp,%rax)
incq %rax
jmp 0x6364
incl %ebx
incl %ebp
jmp 0x6303
testl %ebx, %ebx
je 0x63a9
movl $0x200, %edx            # imm = 0x200
leaq 0x270(%rsp), %rsi
callq 0x6e60
testb %al, %al
movq 0x38(%rsp), %rbx
je 0x63bc
movq 0x8(%rsp), %rax
incl %eax
movq %rax, 0x8(%rsp)
jmp 0x63c8
movq 0x18(%rsp), %rax
incl %eax
movq %rax, 0x18(%rsp)
movq 0x38(%rsp), %rbx
jmp 0x63c8
movq 0x10(%rsp), %rax
incl %eax
movq %rax, 0x10(%rsp)
movq (%rbx), %rdi
callq 0x7aac
incq %r14
testb %al, %al
jne 0x629d
movq 0x17bce(%rip), %rdi     # 0x1dfb0
leaq 0xd211(%rip), %rsi      # 0x135fa
callq 0x5380
movq %rax, %rdi
callq 0x5180
movq 0x17bb3(%rip), %rdi     # 0x1dfb0
callq 0x5180
movq 0x17ba7(%rip), %rdi     # 0x1dfb0
leaq 0xd234(%rip), %rsi      # 0x13644
callq 0x5380
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0x6, 0x10(%rax,%rcx)
movl 0x18(%rsp), %r14d
movq %rax, %rdi
movq %r14, %rsi
callq 0x5240
leaq 0xd21e(%rip), %rsi      # 0x1365a
movq %rax, %rdi
callq 0x5380
movq %rax, %rdi
callq 0x5180
movq 0x17b5d(%rip), %rdi     # 0x1dfb0
leaq 0xd209(%rip), %rsi      # 0x13663
callq 0x5380
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0x6, 0x10(%rax,%rcx)
movl 0x8(%rsp), %r12d
movq %rax, %rdi
movq %r12, %rsi
callq 0x5240
leaq 0xd1fa(%rip), %rsi      # 0x13680
movq %rax, %rdi
callq 0x5380
movq %rax, %rdi
callq 0x5180
movq 0x17b13(%rip), %rdi     # 0x1dfb0
leaq 0xd1e5(%rip), %rsi      # 0x13689
callq 0x5380
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0x6, 0x10(%rax,%rcx)
movl 0x10(%rsp), %esi
movq %rax, %rdi
movq %rsi, 0x60(%rsp)
callq 0x5240
movq %rax, %rdi
callq 0x5180
movq (%rbx), %rdi
callq 0x7b86
cvtsi2sd %r14, %xmm0
movq 0x8(%rsp), %rax
movq 0x10(%rsp), %rcx
addl %ecx, %eax
cvtsi2sd %rax, %xmm1
mulsd 0xcb40(%rip), %xmm1     # 0x13038
ucomisd %xmm1, %xmm0
jbe 0x6526
leaq 0xd1a5(%rip), %rsi      # 0x136aa
pushq $0x1
popq %rax
movl %eax, 0x8(%rbx)
movq 0x17a9e(%rip), %rdi     # 0x1dfb0
callq 0x5380
movb $0x1, %bl
movq %rax, %rdi
callq 0x5180
jmp 0x61ec
cvtsi2sd %r12, %xmm0
movq 0x18(%rsp), %rax
addl %ecx, %eax
cvtsi2sd %rax, %xmm1
mulsd 0xcaf9(%rip), %xmm1     # 0x13038
ucomisd %xmm1, %xmm0
jbe 0x6560
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
cmpq $0x11, %rax
jb 0x6560
leaq 0xd165(%rip), %rsi      # 0x136c1
pushq $0x4
jmp 0x6507
xorpd %xmm0, %xmm0
leaq 0x40(%rsp), %r12
andq $0x0, 0x10(%r12)
movapd %xmm0, (%r12)
xorl %r13d, %r13d
leaq 0x20(%rsp), %rbp
leaq 0x68(%rsp), %r15
movl %r13d, %r13d
movq 0x28(%rsp), %rsi
subq 0x20(%rsp), %rsi
sarq $0x3, %rsi
cmpq %r13, %rsi
jbe 0x65d1
movq %rbp, %rdi
movq %r13, %rsi
callq 0x6f22
movq (%rax), %rdi
callq 0xf544
movq %rax, 0x68(%rsp)
movl $0x200, %edx            # imm = 0x200
movq %rax, %rsi
callq 0x6e60
testb %al, %al
jne 0x65cc
movq %r12, %rdi
movq %r15, %rsi
callq 0x6fe8
incl %r13d
jmp 0x6582
movq 0x48(%rsp), %rax
subq 0x40(%rsp), %rax
cmpq $0x10, %rax
jne 0x6628
leaq 0x40(%rsp), %rdi
xorl %esi, %esi
callq 0x7006
movq (%rax), %r15
leaq 0x40(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x7006
movq (%rax), %rdx
movl $0x200, %ecx            # imm = 0x200
movq %r15, %rsi
callq 0x6e7c
testb %al, %al
je 0x661a
leaq 0xd0c9(%rip), %rsi      # 0x136e1
jmp 0x666a
movq 0x28(%rsp), %rsi
subq 0x20(%rsp), %rsi
sarq $0x3, %rsi
imull $0x64, 0x10(%rsp), %eax
incq %rsi
xorl %ecx, %ecx
xorl %edx, %edx
divq %rsi
cmpl %r14d, %eax
jbe 0x6696
movq 0x18(%rsp), %rax
addl 0x8(%rsp), %eax
cvtsi2sd %rax, %xmm0
cvtsi2ssq 0x60(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
mulsd 0xc9e3(%rip), %xmm1     # 0x13040
ucomisd %xmm1, %xmm0
jbe 0x66a2
leaq 0xd0c0(%rip), %rsi      # 0x1372a
movl $0x1, 0x28(%rbx)
movl $0x3, 0x8(%rbx)
movq 0x17931(%rip), %rdi     # 0x1dfb0
callq 0x5380
movq %rax, %rdi
callq 0x5180
movq (%rbx), %rdi
callq 0x7b86
jmp 0x66c0
leaq 0xd0eb(%rip), %rsi      # 0x13788
pushq $0x1
popq %rcx
jmp 0x66a9
leaq 0xd11f(%rip), %rsi      # 0x137c8
movl %ecx, 0x8(%rbx)
movq 0x178fd(%rip), %rdi     # 0x1dfb0
callq 0x5380
movq %rax, %rdi
callq 0x5180
leaq 0x40(%rsp), %rdi
callq 0x7230
movb $0x1, %bl
jmp 0x61ec
jmp 0x66ec
jmp 0x66d9
jmp 0x66ec
jmp 0x66ec
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x7230
jmp 0x66ef
jmp 0x66ec
jmp 0x66ec
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x714e
movq %rbx, %rdi
callq 0x5610
nop