// File: /workspace/github_cpp_makefile_star2_O3/Windfisch[P]production-flow/factory.cpp
// Function: Factory::build_flowgraph(item_t, Factory::FactoryConfiguration const&) const
FlowGraph Factory::build_flowgraph(item_t item, const Factory::FactoryConfiguration& conf) const
{
	const auto& toposort = facility_toposort[item];
	const auto& toposort_inv = facility_toposort_inv[item];
	const auto& edge_table = edge_table_per_item[item];

	FlowGraph flowgraph;
	flowgraph.edges.reserve(edge_table.size());
	flowgraph.nodes.reserve(toposort.size());


	// insert all facilities that are relevant for `item` into the flowgraph,
	// topologically sorted from producers to consumers.
	for (size_t facility_index : toposort)
	{
		const auto& facility = facilities[facility_index];
		size_t level = conf.facility_levels[facility_index];
		int production_rate;
		auto iter = facility.upgrade_plan[level].production_or_consumption.find(item);
		if (iter != facility.upgrade_plan[level].production_or_consumption.end())
			production_rate = iter->second;
		else
			production_rate = 0;

		flowgraph.nodes.emplace_back(production_rate);
	}

	// insert all transport lines that are relevant for `item`
	for (size_t edge_index = 0; edge_index < edge_table.size(); edge_index++)
	{
		const auto& edge = transport_lines[edge_table[edge_index]];
		assert(edge.item_type == item);
		size_t level = conf.transport_levels[edge_table[edge_index]];
		int capacity = edge.upgrade_plan[level].capacity;
	
		flowgraph.edges.emplace_back(capacity);
	}

	// fill the nodes' edgetables.
	for (size_t edge_index = 0; edge_index < edge_table.size(); edge_index++)
	{
		const auto& edge = transport_lines[edge_table[edge_index]];
		assert(edge.item_type == item);

		flowgraph.nodes[toposort_inv[edge.from]].outgoing_edges.push_back(
			&flowgraph.edges[edge_index]);
		flowgraph.nodes[toposort_inv[edge.to  ]].incoming_edges.push_back(
			&flowgraph.edges[edge_index]);
	}

	return flowgraph;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rcx, 0x8(%rsp)
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %rbx
movslq %edx, %rax
shlq $0x3, %rax
leaq (%rax,%rax,2), %rcx
movq 0x30(%rsi), %r15
addq %rcx, %r15
movq 0x48(%rsi), %rax
addq %rcx, %rax
movq %rax, 0x30(%rsp)
movq 0x60(%rsi), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rdi)
movups %xmm0, 0x10(%rdi)
movups %xmm0, (%rdi)
addq $0x18, %rdi
movq 0x8(%rax,%rcx), %rsi
movq %rax, 0x10(%rsp)
movq %rcx, 0x20(%rsp)
subq (%rax,%rcx), %rsi
sarq $0x3, %rsi
movq %rdi, %r13
movq %rbx, 0x18(%rsp)
callq 0x6412
movq 0x8(%r15), %rsi
subq (%r15), %rsi
sarq $0x3, %rsi
movq %rbx, %rdi
callq 0x64d4
movq (%r15), %r12
movq 0x8(%r15), %r15
cmpq %r15, %r12
je 0x5990
movq (%r12), %rax
movq (%r14), %rdx
leaq (%rax,%rax,4), %rsi
shlq $0x4, %rsi
movq 0x8(%rsp), %rcx
movq (%rcx), %rcx
imulq $0x38, (%rcx,%rax,8), %rcx
movq (%rdx,%rsi), %rsi
movq 0x10(%rsi,%rcx), %rdx
xorl %eax, %eax
testq %rdx, %rdx
je 0x597c
addq %rcx, %rsi
addq $0x8, %rsi
movq %rsi, %rcx
xorl %edi, %edi
cmpl %ebp, 0x20(%rdx)
setl %dil
cmovgeq %rdx, %rcx
movq 0x10(%rdx,%rdi,8), %rdx
testq %rdx, %rdx
jne 0x5958
cmpq %rsi, %rcx
je 0x597c
cmpl %ebp, 0x20(%rcx)
jg 0x597c
movl 0x24(%rcx), %eax
movl %eax, (%rsp)
movq %rbx, %rdi
movq %rsp, %rsi
callq 0x6568
addq $0x8, %r12
jmp 0x591d
movq 0x10(%rsp), %r12
addq 0x20(%rsp), %r12
movq (%r12), %rax
movq 0x8(%r12), %rcx
cmpq %rax, %rcx
je 0x5a08
xorl %r15d, %r15d
movq (%rax,%r15,8), %rax
movq 0x18(%r14), %rcx
leaq (%rax,%rax,2), %rdx
shlq $0x4, %rdx
cmpl %ebp, (%rcx,%rdx)
jne 0x5aef
addq %rdx, %rcx
movq 0x8(%rsp), %rdx
movq 0x18(%rdx), %rdx
movq (%rdx,%rax,8), %rax
movq 0x18(%rcx), %rcx
shlq $0x4, %rax
movl (%rcx,%rax), %eax
movl %eax, (%rsp)
movq %r13, %rdi
movq %rsp, %rsi
callq 0x65b4
incq %r15
movq (%r12), %rax
movq 0x8(%r12), %rcx
movq %rcx, %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %rdx, %r15
jb 0x59ab
movl %ebp, 0x8(%rsp)
movq %r12, 0x10(%rsp)
cmpq %rax, %rcx
je 0x5add
xorl %r12d, %r12d
movq %rsp, %rbp
xorl %r15d, %r15d
movq %r14, 0x28(%rsp)
movq 0x18(%rsp), %rbx
movq (%rax,%r15,8), %rax
movq 0x18(%r14), %r14
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
movl 0x8(%rsp), %ecx
cmpl %ecx, (%r14,%rax)
jne 0x5b0e
addq %rax, %r14
movq 0x8(%r14), %rax
movq 0x30(%rsp), %r13
movq (%r13), %rcx
movq (%rcx,%rax,8), %rax
movq (%rbx), %rcx
shlq $0x6, %rax
leaq (%rcx,%rax), %rdi
addq $0x28, %rdi
movq 0x18(%rbx), %rax
addq %r12, %rax
movq %rax, (%rsp)
movq %rbp, %rsi
callq 0x7736
movq 0x10(%r14), %rax
movq (%r13), %rcx
movq (%rcx,%rax,8), %rax
movq (%rbx), %rcx
shlq $0x6, %rax
leaq (%rcx,%rax), %rdi
addq $0x10, %rdi
movq 0x18(%rbx), %rax
addq %r12, %rax
movq %rax, (%rsp)
movq %rbp, %r13
movq %rbp, %rsi
callq 0x7736
incq %r15
movq 0x10(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
addq $0xc, %r12
cmpq %rcx, %r15
movq 0x28(%rsp), %r14
movq %r13, %rbp
jb 0x5a2d
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x985a(%rip), %rdi      # 0xf350
leaq 0x97d3(%rip), %rsi      # 0xf2d0
leaq 0x9863(%rip), %rcx      # 0xf367
movl $0xbb, %edx
callq 0x3180
leaq 0x983b(%rip), %rdi      # 0xf350
leaq 0x97b4(%rip), %rsi      # 0xf2d0
leaq 0x9844(%rip), %rcx      # 0xf367
movl $0xc6, %edx
callq 0x3180
jmp 0x5b35
jmp 0x5b35
jmp 0x5b35
jmp 0x5b35
movq %rax, %r14
movq 0x18(%rsp), %rdi
callq 0x65f2
movq %r14, %rdi
callq 0x3400