// File: narges64[P]SIMBA/garbage_collection.cpp
// Function: find_victim_block(ssd_info*, local*)
STATE find_victim_block(ssd_info * ssd, local * location){
	high_resolution_clock::time_point t1 = high_resolution_clock::now();
	switch (ssd->parameter->gc_algorithm) {
		case GREEDY:
				greedy_algorithm(ssd, location);

				break;
		case FIFO:
				fifo_algorithm(ssd, location);

				break;
		case WINDOWED:
				windowed_algorithm(ssd, location);

				break;
		case RGA:
				RGA_algorithm(ssd, location); // select the best one based on valid number

				break;
		case RANDOM:
				RANDOM_algorithm(ssd, location);

				break;
		case RANDOMP:
				RANDOM_p_algorithm(ssd, location);

				break;
		case RANDOMPP:
				RANDOM_pp_algorithm(ssd, location);

				break;

		default:
		{
			printf("Wrong garbage collection in parameters %d\n", ssd->parameter->gc_algorithm);
			return ERROR;
		}

	}

  	high_resolution_clock::time_point t2 = high_resolution_clock::now();
  	double dif = duration_cast<nanoseconds>( t2 - t1 ).count();
  	// printf ("Elasped time is %lf nanoseconds.\n", dif );

	if (location->block == -1){
		printf("Error: Problem in finding the victim block, time: %lld    gc alg %d \n", ssd->current_time , ssd->parameter->gc_algorithm );
		return FAIL;

	}

	if (ssd->channel_head[location->channel]->lun_head[location->lun]->	
								plane_head[location->plane]->blk_head[location->block]->free_page_num >= ssd->parameter->page_block){
		cout << "Error: too much free page in selected victim \n";
		
		cout << ssd->channel_head[location->channel]->lun_head[location->lun]->plane_head[location->plane]->blk_head[location->block]->free_page_num << endl;
		return FAIL;
	}

	return SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
callq 0x2060
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movl 0x74(%rax), %eax
movq %rax, -0x48(%rbp)
subq $0x6, %rax
ja 0xa0ab
movq -0x48(%rbp), %rax
leaq 0x5937(%rip), %rcx      # 0xf970
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xab60
jmp 0xa0d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xabf0
jmp 0xa0d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xad30
jmp 0xa0d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xad50
jmp 0xa0d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xb010
jmp 0xa0d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xb110
jmp 0xa0d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xb200
jmp 0xa0d0
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movl 0x74(%rax), %esi
leaq 0x5925(%rip), %rdi      # 0xf9e2
movb $0x0, %al
callq 0x2050
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xa21e
callq 0x2060
movq %rax, -0x28(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0xba40
movq %rax, -0x40(%rbp)
leaq -0x40(%rbp), %rdi
callq 0xba10
movq %rax, -0x38(%rbp)
leaq -0x38(%rbp), %rdi
callq 0xba90
cvtsi2sd %rax, %xmm0
movsd %xmm0, -0x30(%rbp)
movq -0x18(%rbp), %rax
cmpl $-0x1, 0xc(%rax)
jne 0xa140
movq -0x10(%rbp), %rax
movq (%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movl 0x74(%rax), %edx
leaq 0x58e0(%rip), %rdi      # 0xfa0d
movb $0x0, %al
callq 0x2050
movl $0x0, -0x4(%rbp)
jmp 0xa21e
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movq -0x18(%rbp), %rcx
movslq 0x4(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movq -0x18(%rbp), %rcx
movslq 0xc(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
movq 0x58(%rcx), %rcx
cmpl 0x234(%rcx), %eax
jb 0xa217
movq 0x9e31(%rip), %rdi      # 0x13fd0
leaq 0x58ad(%rip), %rsi      # 0xfa53
callq 0x2110
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movq -0x18(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movq -0x18(%rbp), %rcx
movslq 0x4(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
movslq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movq -0x18(%rbp), %rcx
movslq 0xc(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movl 0x4(%rax), %esi
movq 0x9dd6(%rip), %rdi      # 0x13fd0
callq 0x2220
movq %rax, %rdi
movq 0x9db7(%rip), %rsi      # 0x13fc0
callq 0x2150
movl $0x0, -0x4(%rbp)
jmp 0xa21e
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)