// File: /workspace/github_cpp_makefile_star2_O2/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 $0x48, %rsp
movq %rcx, 0x10(%rsp)
movq %rsi, %r14
movq %rdi, %rbx
movl %edx, 0xc(%rsp)
movslq %edx, %rax
imulq $0x18, %rax, %rbp
movq 0x30(%rsi), %r13
addq %rbp, %r13
movq 0x48(%rsi), %r15
addq %rbp, %r15
movq 0x60(%rsi), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x20(%rdi)
movups %xmm0, 0x10(%rdi)
movups %xmm0, (%rdi)
addq $0x18, %rdi
movq 0x8(%rax,%rbp), %rsi
movq %rax, 0x20(%rsp)
subq (%rax,%rbp), %rsi
sarq $0x3, %rsi
movq %rdi, 0x38(%rsp)
callq 0x5b1a
movq 0x8(%r13), %rsi
subq (%r13), %rsi
sarq $0x3, %rsi
movq %rbx, %rdi
callq 0x5be0
addq %rbp, 0x20(%rsp)
movq (%r13), %rax
movq 0x8(%r13), %rcx
movq %rcx, 0x40(%rsp)
movq %r15, 0x30(%rsp)
cmpq 0x40(%rsp), %rax
je 0x5342
movq %rax, %rbp
movq (%rax), %rax
movq %r14, %r12
movq (%r14), %r15
imulq $0x50, %rax, %r14
movq 0x10(%rsp), %rcx
movq (%rcx), %rcx
imulq $0x38, (%rcx,%rax,8), %r13
movq (%r15,%r14), %rdi
addq %r13, %rdi
leaq 0xc(%rsp), %rsi
callq 0x702e
addq %r14, %r15
movq (%r15), %rcx
addq %r13, %rcx
addq $0x8, %rcx
cmpq %rcx, %rax
je 0x5323
movl 0x24(%rax), %eax
jmp 0x5325
xorl %eax, %eax
movl %eax, 0x18(%rsp)
movq %rbx, %rdi
leaq 0x18(%rsp), %rsi
callq 0x5c74
movq %rbp, %rax
addq $0x8, %rax
movq %r12, %r14
jmp 0x52d7
xorl %ebp, %ebp
leaq 0x18(%rsp), %r13
movq 0x20(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
movq %rcx, %rdx
subq %rax, %rdx
sarq $0x3, %rdx
cmpq %rdx, %rbp
jae 0x53ae
movq (%rax,%rbp,8), %rax
movq 0x18(%r14), %rcx
imulq $0x30, %rax, %rdx
movl (%rcx,%rdx), %esi
cmpl 0xc(%rsp), %esi
jne 0x548e
addq %rdx, %rcx
movq 0x10(%rsp), %rdx
movq 0x18(%rdx), %rdx
movq (%rdx,%rax,8), %rax
movq 0x18(%rcx), %rcx
shlq $0x4, %rax
movl (%rcx,%rax), %eax
movl %eax, 0x18(%rsp)
movq 0x38(%rsp), %rdi
movq %r13, %rsi
callq 0x5cbe
incq %rbp
jmp 0x5349
movq %rbx, 0x10(%rsp)
xorl %ebp, %ebp
leaq 0x18(%rsp), %r12
xorl %esi, %esi
movq %r14, 0x28(%rsp)
movq 0x10(%rsp), %rbx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %rcx, %rsi
jae 0x547a
imulq $0x30, (%rax,%rsi,8), %rax
movq 0x18(%r14), %r15
movl (%r15,%rax), %ecx
cmpl 0xc(%rsp), %ecx
jne 0x54ad
movq %rsi, %r13
addq %rax, %r15
movq 0x8(%r15), %rax
movq 0x30(%rsp), %r14
movq (%r14), %rcx
movq (%rcx,%rax,8), %rax
movq (%rbx), %rcx
shlq $0x6, %rax
leaq (%rcx,%rax), %rdi
addq $0x28, %rdi
movq 0x18(%rbx), %rax
addq %rbp, %rax
movq %rax, 0x18(%rsp)
movq %r12, %rsi
callq 0x72c4
movq 0x10(%r15), %rax
movq (%r14), %rcx
movq (%rcx,%rax,8), %rax
movq (%rbx), %rcx
shlq $0x6, %rax
leaq (%rcx,%rax), %rdi
addq $0x10, %rdi
movq 0x18(%rbx), %rax
addq %rbp, %rax
movq %rax, 0x18(%rsp)
movq %r12, %r15
movq %r12, %rsi
callq 0x72c4
movq %r13, %rsi
incq %rsi
movq 0x20(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
addq $0xc, %rbp
movq %r15, %r12
movq 0x28(%rsp), %r14
jmp 0x53c6
movq 0x10(%rsp), %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x7ec2(%rip), %rdi      # 0xd357
leaq 0x7e3b(%rip), %rsi      # 0xd2d7
leaq 0x7ecb(%rip), %rcx      # 0xd36e
movl $0xbb, %edx
callq 0x3170
leaq 0x7ea3(%rip), %rdi      # 0xd357
leaq 0x7e1c(%rip), %rsi      # 0xd2d7
leaq 0x7eac(%rip), %rcx      # 0xd36e
movl $0xc6, %edx
callq 0x3170
jmp 0x54dc
movq %rax, %r14
movq 0x10(%rsp), %rbx
jmp 0x54df
jmp 0x54dc
jmp 0x54dc
movq %rax, %r14
movq %rbx, %rdi
callq 0x5cfa
movq %r14, %rdi
callq 0x33c0
nop