// File: /workspace/github_cpp_makefile_star2_O2/CMU-SAFARI[P]MQSim/src/main.cpp
// Function: main
int main(int argc, char* argv[])
{
	string ssd_config_file_path, workload_defs_file_path;
	if (argc != 5) {
		// MQSim expects 2 arguments: 1) the path to the SSD configuration definition file, and 2) the path to the workload definition file
		print_help();
		return 1;
	}

	command_line_args(argv, ssd_config_file_path, workload_defs_file_path);

	Execution_Parameter_Set* exec_params = new Execution_Parameter_Set;
	read_configuration_parameters(ssd_config_file_path, exec_params);
	std::vector<std::vector<IO_Flow_Parameter_Set*>*>* io_scenarios = read_workload_definitions(workload_defs_file_path);

	int cntr = 1;
	for (auto io_scen = io_scenarios->begin(); io_scen != io_scenarios->end(); io_scen++, cntr++) {
		time_t start_time = time(0);
		char* dt = ctime(&start_time);
		PRINT_MESSAGE("MQSim started at " << dt)
		PRINT_MESSAGE("******************************")
		PRINT_MESSAGE("Executing scenario " << cntr << " out of " << io_scenarios->size() << " .......")

		//The simulator should always be reset, before starting the actual simulation
		Simulator->Reset();

		exec_params->Host_Configuration.IO_Flow_Definitions.clear();
		for (auto io_flow_def = (*io_scen)->begin(); io_flow_def != (*io_scen)->end(); io_flow_def++) {
			exec_params->Host_Configuration.IO_Flow_Definitions.push_back(*io_flow_def);
		}

		SSD_Device ssd(&exec_params->SSD_Device_Configuration, &exec_params->Host_Configuration.IO_Flow_Definitions);//Create SSD_Device based on the specified parameters
		exec_params->Host_Configuration.Input_file_path = workload_defs_file_path.substr(0, workload_defs_file_path.find_last_of("."));//Create Host_System based on the specified parameters
		Host_System host(&exec_params->Host_Configuration, exec_params->SSD_Device_Configuration.Enabled_Preconditioning, ssd.Host_interface);
		host.Attach_ssd_device(&ssd);

		Simulator->Start_simulation();

		time_t end_time = time(0);
		dt = ctime(&end_time);
		PRINT_MESSAGE("MQSim finished at " << dt)
		uint64_t duration = (uint64_t)difftime(end_time, start_time);
		PRINT_MESSAGE("Total simulation time: " << duration / 3600 << ":" << (duration % 3600) / 60 << ":" << ((duration % 3600) % 60))
		PRINT_MESSAGE("");

		PRINT_MESSAGE("Writing results to output file .......");
		collect_results(ssd, host, (workload_defs_file_path.substr(0, workload_defs_file_path.find_last_of(".")) + "_scenario_" + std::to_string(cntr) + ".xml").c_str());
	}
    cout << "Simulation complete; Press any key to exit." << endl;

	cin.get(); // Disable if you prefer batch runs

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x258, %rsp            # imm = 0x258
leaq 0x40(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
leaq 0x20(%rsp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
xorl %edx, %edx
movb %dl, (%rax)
movb %dl, (%rcx)
cmpl $0x5, %edi
jne 0x9769
leaq 0x30(%rsp), %rax
leaq 0x10(%rsp), %rdx
movq %rsi, %rdi
movq %rax, %rsi
callq 0x826c
pushq $0x8
popq %rdi
callq 0x7370
movq %rax, %rbx
leaq 0x5755e(%rip), %rax     # 0x608a0
addq $0x10, %rax
movq %rax, (%rbx)
leaq 0xd8(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x7480
leaq 0xd8(%rsp), %rdi
movq %rbx, %rsi
callq 0x8358
leaq 0xd8(%rsp), %rdi
callq 0x7678
leaq 0xb8(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x7480
leaq 0xb8(%rsp), %rdi
callq 0x8770
movq %rax, %r15
leaq 0xb8(%rsp), %rdi
callq 0x7678
movq (%r15), %rbx
pushq $0x1
popq %rbp
leaq 0x591b4(%rip), %r14     # 0x62568
cmpq 0x8(%r15), %rbx
je 0x9773
xorl %edi, %edi
callq 0x7320
movq %rax, 0x8(%rsp)
leaq 0x8(%rsp), %rdi
callq 0x7140
movq %rax, %r12
movq 0x58b9a(%rip), %rdi     # 0x61f78
leaq 0x3a059(%rip), %rsi     # 0x4343e
callq 0x7360
movq %rax, %rdi
movq %r12, %rsi
callq 0x7360
movq %rax, %rdi
callq 0x71a0
movq 0x58b74(%rip), %rdi     # 0x61f78
leaq 0x3a045(%rip), %rsi     # 0x43450
callq 0x7360
movq %rax, %rdi
callq 0x71a0
movq 0x58b59(%rip), %rdi     # 0x61f78
leaq 0x3a049(%rip), %rsi     # 0x4346f
callq 0x7360
movq %rax, %rdi
movl %ebp, %esi
callq 0x75a0
movq %rax, %rdi
leaq 0x3a044(%rip), %rsi     # 0x43483
callq 0x7360
movq 0x8(%r15), %rsi
subq (%r15), %rsi
sarq $0x3, %rsi
movq %rax, %rdi
callq 0x7270
movq %rax, %rdi
leaq 0x3a074(%rip), %rsi     # 0x434d5
callq 0x7360
movq %rax, %rdi
callq 0x71a0
callq 0x1f784
movq %rax, %rdi
callq 0x1f7cc
movq (%r14), %rax
cmpq %rax, 0x8(%r14)
je 0x9488
movq %rax, 0x8(%r14)
movq (%rbx), %rax
movq (%rax), %r12
cmpq 0x8(%rax), %r12
je 0x94a8
movq %r14, %rdi
movq %r12, %rsi
callq 0x9a50
addq $0x8, %r12
movq (%rbx), %rax
jmp 0x948e
leaq 0x158(%rsp), %rdi
leaq 0x58f39(%rip), %rsi     # 0x623f0
movq %r14, %rdx
callq 0x14bb0
leaq 0x10(%rsp), %r12
movq %r12, %rdi
leaq 0x3a00e(%rip), %rsi     # 0x434dc
pushq $-0x1
popq %rdx
callq 0x7350
leaq 0x1d8(%rsp), %r13
movq %r13, %rdi
movq %r12, %rsi
xorl %edx, %edx
movq %rax, %rcx
callq 0x7380
leaq 0x59053(%rip), %rdi     # 0x62548
movq %r13, %rsi
callq 0x73f0
movq %r13, %rdi
callq 0x7678
leaq 0x58e40(%rip), %rax     # 0x6234c
movzbl (%rax), %edx
movq 0x198(%rsp), %rcx
movq %r13, %rdi
leaq 0x58ec7(%rip), %rsi     # 0x623e8
callq 0x10af0
movq %r13, %rdi
leaq 0x158(%rsp), %rsi
callq 0x11750
callq 0x1f784
movq %rax, %rdi
callq 0x1fa34
xorl %edi, %edi
callq 0x7320
movq %rax, (%rsp)
movq %rsp, %rdi
callq 0x7140
movq %rax, %r12
movq 0x58a18(%rip), %rdi     # 0x61f78
leaq 0x39f25(%rip), %rsi     # 0x4348c
callq 0x7360
movq %rax, %rdi
movq %r12, %rsi
callq 0x7360
movq %rax, %rdi
callq 0x71a0
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x71c0
movapd %xmm0, 0x50(%rsp)
subsd 0x39ab5(%rip), %xmm0    # 0x43050
movapd %xmm0, 0x60(%rsp)
movq 0x589d0(%rip), %rdi     # 0x61f78
leaq 0x39ef0(%rip), %rsi     # 0x4349f
callq 0x7360
movq %rax, %rdi
cvttsd2si 0x50(%rsp), %rcx
movq %rcx, %rdx
cvttsd2si 0x60(%rsp), %rax
sarq $0x3f, %rdx
andq %rdx, %rax
orq %rcx, %rax
xorl %edx, %edx
movl $0xe10, %ecx            # imm = 0xE10
divq %rcx
movq %rdx, %r12
movq %rax, %rsi
callq 0x7270
movq %rax, %rdi
leaq 0x3af9c(%rip), %rsi     # 0x4458d
callq 0x7360
movq %rax, %rdi
movl %r12d, %eax
xorl %edx, %edx
movw $0x3c, %cx
divw %cx
movl %edx, %r12d
movzwl %ax, %esi
callq 0x7270
movq %rax, %rdi
leaq 0x3af73(%rip), %rsi     # 0x4458d
callq 0x7360
movzwl %r12w, %esi
movq %rax, %rdi
callq 0x7270
movq %rax, %rdi
callq 0x71a0
movq 0x5893e(%rip), %rdi     # 0x61f78
leaq 0x3c2aa(%rip), %rsi     # 0x458eb
callq 0x7360
movq %rax, %rdi
callq 0x71a0
movq 0x58923(%rip), %rdi     # 0x61f78
leaq 0x39e5b(%rip), %rsi     # 0x434b7
callq 0x7360
movq %rax, %rdi
callq 0x71a0
leaq 0x10(%rsp), %r12
movq %r12, %rdi
leaq 0x39e64(%rip), %rsi     # 0x434dc
pushq $-0x1
popq %rdx
callq 0x7350
leaq 0x118(%rsp), %r13
movq %r13, %rdi
movq %r12, %rsi
xorl %edx, %edx
movq %rax, %rcx
callq 0x7380
leaq 0x78(%rsp), %rdi
movq %r13, %rsi
leaq 0x39e37(%rip), %rdx     # 0x434de
callq 0x9b29
leaq 0xf8(%rsp), %r12
movq %r12, %rdi
movl %ebp, %esi
callq 0x9baf
leaq 0x138(%rsp), %r13
movq %r13, %rdi
leaq 0x78(%rsp), %rsi
movq %r12, %rdx
callq 0x9b48
leaq 0x98(%rsp), %rdi
movq %r13, %rsi
leaq 0x39e01(%rip), %rdx     # 0x434e9
callq 0x9b29
movq 0x98(%rsp), %rdx
leaq 0x158(%rsp), %r12
movq %r12, %rdi
leaq 0x1d8(%rsp), %r13
movq %r13, %rsi
callq 0x8f7d
leaq 0x98(%rsp), %rdi
callq 0x7678
leaq 0x138(%rsp), %rdi
callq 0x7678
leaq 0xf8(%rsp), %rdi
callq 0x7678
leaq 0x78(%rsp), %rdi
callq 0x7678
leaq 0x118(%rsp), %rdi
callq 0x7678
movq %r13, %rdi
callq 0x11686
movq %r12, %rdi
callq 0x168ae
addq $0x8, %rbx
incl %ebp
jmp 0x93b4
callq 0x9294
pushq $0x1
popq %rbx
jmp 0x979c
movq 0x587fe(%rip), %rdi     # 0x61f78
leaq 0x39d6d(%rip), %rsi     # 0x434ee
callq 0x7360
movq %rax, %rdi
callq 0x71a0
xorl %ebx, %ebx
movq 0x58839(%rip), %rdi     # 0x61fd0
callq 0x73d0
leaq 0x10(%rsp), %rdi
callq 0x7678
leaq 0x30(%rsp), %rdi
callq 0x7678
movl %ebx, %eax
addq $0x258, %rsp            # imm = 0x258
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
jmp 0x97e1
jmp 0x9881
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0x7678
jmp 0x9884
jmp 0x9881
jmp 0x9881
jmp 0x9881
movq %rax, %rbx
jmp 0x9833
movq %rax, %rbx
jmp 0x9826
movq %rax, %rbx
jmp 0x9819
movq %rax, %rbx
leaq 0x98(%rsp), %rdi
callq 0x7678
leaq 0x138(%rsp), %rdi
callq 0x7678
leaq 0xf8(%rsp), %rdi
callq 0x7678
leaq 0x78(%rsp), %rdi
callq 0x7678
jmp 0x9844
jmp 0x9860
movq %rax, %rbx
leaq 0x118(%rsp), %rdi
callq 0x7678
jmp 0x9863
jmp 0x9881
jmp 0x9857
movq %rax, %rbx
jmp 0x9870
jmp 0x9860
jmp 0x9860
movq %rax, %rbx
leaq 0x1d8(%rsp), %rdi
callq 0x11686
leaq 0x158(%rsp), %rdi
callq 0x168ae
jmp 0x9884
jmp 0x9881
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x7678
leaq 0x30(%rsp), %rdi
callq 0x7678
movq %rbx, %rdi
callq 0x75d0