// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/rcut.cpp
// Function: mc_solve_cc(mc_opt_t const*, mc_g_t const*, mc_svaux_t*, unsigned int, unsigned int)
uint32_t mc_solve_cc(const mc_opt_t *opt, const mc_g_t *mg, mc_svaux_t *b, uint32_t cc_off, uint32_t cc_size)
{
	uint32_t j, k, n_iter = 0, flush = opt->max_iter * 50;
	t_w_t sc_opt = -(1<<30), sc;///problem-w
	b->cc_off = cc_off, b->cc_size = cc_size;
	if (b->cc_size < 2) return 0;
	sc_opt = mc_init_spin(mg->e, b);
	// print_sc(opt, mg, b, sc_opt, n_iter);
	if (b->cc_size == 2) return 0;
	for (j = 0; j < b->cc_size; ++j) {///backup s and z in s_opt and z_opt
		b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]]; ///hap status of each unitig
		b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]]; ///z[0]: positive weight; z[1]: positive weight
	}
	// print_sc(opt, mg->e, b, sc_opt, n_iter);
	sc = mc_optimize_local(opt, mg->e, b, &n_iter);
	if (sc > sc_opt) {
		for (j = 0; j < b->cc_size; ++j) {
			b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]];
			b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
		}
		sc_opt = sc;
	} else {
		for (j = 0; j < b->cc_size; ++j) {
			b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
			b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
		}
	}

    // print_mc_node(mg->e, b, 36880);
	// print_sc(opt, mg, b, sc_opt, n_iter);
	// mc_reset_z_debug(mg->e, b);
	// print_sc(opt, mg->e, b, sc_opt, n_iter);
	// fprintf(stderr, "\ncc_size: %u, cc_off: %u\n", b->cc_size, b->cc_off);
	for (k = 0; k < (uint32_t)opt->n_perturb; ++k) {
		if (k&1) mc_perturb(opt, mg->e, b);
		else mc_perturb_node(opt, mg->e, b, 3);
		sc = mc_optimize_local(opt, mg->e, b, &n_iter);
		// fprintf(stderr, "(%u) sc_opt: %f, sc: %f\n", k, sc_opt, sc);
		if (sc > sc_opt) {
			for (j = 0; j < b->cc_size; ++j) {
				b->s_opt[b->cc_node[j]] = b->s[b->cc_node[j]];
				b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
			}
			sc_opt = sc;
			// print_sc(opt, mg, b, sc_opt, n_iter);
		} else {
			for (j = 0; j < b->cc_size; ++j) {
				b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
				b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
			}
		}

		if((n_iter%flush) == 0)
		{
			mc_reset_z(mg->e, b);
			sc = mc_score(mg->e, b);

			for (j = 0; j < b->cc_size; ++j) {
				b->z_opt[b->cc_node[j]] = b->z[b->cc_node[j]];
			}
			sc_opt = sc;
		}
	}

	for (j = 0; j < b->cc_size; ++j)
	{
		b->s[b->cc_node[j]] = b->s_opt[b->cc_node[j]];
		b->z[b->cc_node[j]] = b->z_opt[b->cc_node[j]];
	}
		
	return n_iter;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
andl $0x0, 0xc(%rsp)
imull $0x32, (%rdi), %r13d
movl %ecx, 0x8(%rdx)
movl %r8d, 0xc(%rdx)
xorl %ebp, %ebp
cmpl $0x2, %r8d
jb 0x126d4d
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, %r15
movq 0x28(%rsi), %rdi
movq %rdx, %rsi
callq 0x125a9f
movl 0xc(%rbx), %ecx
cmpl $0x2, %ecx
je 0x126d4d
xorl %eax, %eax
movl %ecx, %ecx
cmpq %rcx, %rax
jae 0x126b2f
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm1
movupd %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
jmp 0x126aee
movq 0x28(%r14), %rsi
leaq 0xc(%rsp), %rcx
movq %r15, %rdi
movq %rbx, %rdx
movsd %xmm0, 0x10(%rsp)
callq 0x126d5e
movsd 0x10(%rsp), %xmm1
xorl %eax, %eax
ucomisd %xmm1, %xmm0
jbe 0x126b96
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x126bd9
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm1
movupd %xmm1, (%rsi,%rcx)
incq %rax
jmp 0x126b57
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x126bd5
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
jmp 0x126b96
movapd %xmm1, %xmm0
xorl %ebp, %ebp
leaq 0xc(%rsp), %r12
cmpl 0x4(%r15), %ebp
jae 0x126d06
movsd %xmm0, 0x10(%rsp)
movq 0x28(%r14), %rsi
movq %r15, %rdi
movq %rbx, %rdx
testb $0x1, %bpl
jne 0x126c07
callq 0x126e6c
jmp 0x126c0c
callq 0x126e09
movq 0x28(%r14), %rsi
movq %r15, %rdi
movq %rbx, %rdx
movq %r12, %rcx
callq 0x126d5e
movsd 0x10(%rsp), %xmm1
xorl %eax, %eax
ucomisd %xmm1, %xmm0
ja 0x126c63
jmp 0x126ca2
movq 0x28(%rbx), %rcx
movq 0x50(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
movb (%rdx,%rcx), %dl
movq 0x58(%rbx), %rsi
movb %dl, (%rsi,%rcx)
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm1
movupd %xmm1, (%rsi,%rcx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x126c2e
jmp 0x126cae
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jb 0x126c6d
movapd %xmm1, %xmm0
movl 0xc(%rsp), %eax
xorl %edx, %edx
divl %r13d
testl %edx, %edx
je 0x126cc2
incl %ebp
jmp 0x126be0
movq 0x28(%r14), %rdi
movq %rbx, %rsi
callq 0x1258d9
movq 0x28(%r14), %rdi
movq %rbx, %rsi
callq 0x12584f
xorl %eax, %eax
movl 0xc(%rbx), %ecx
cmpq %rcx, %rax
jae 0x126cbb
movq 0x28(%rbx), %rcx
movq 0x40(%rbx), %rdx
movl (%rcx,%rax,4), %ecx
shlq $0x4, %rcx
movq 0x48(%rbx), %rsi
movupd (%rdx,%rcx), %xmm1
movupd %xmm1, (%rsi,%rcx)
incq %rax
jmp 0x126cdc
xorl %eax, %eax
movl %ecx, %ecx
cmpq %rcx, %rax
jae 0x126d49
movq 0x58(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x50(%rbx), %rsi
movl (%rdx,%rax,4), %edx
movb (%rcx,%rdx), %cl
movb %cl, (%rsi,%rdx)
movq 0x48(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
movl (%rdx,%rax,4), %edx
shlq $0x4, %rdx
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%rsi,%rdx)
incq %rax
movl 0xc(%rbx), %ecx
jmp 0x126d08
movl 0xc(%rsp), %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq