// File: /workspace/github_cpp_makefile_star2_O2/jmfenner92[P]Log-Parser/src/log_parser.cpp
// Function: main
int main(int argc, char** argv) {

	// check the number of arguments. it should be 2: one for the name of the program and 
	// one for the log file to be read in
	if (argc != 2) {
		cerr << "Invalid number of arguments!" << endl;
		cerr << "Usage: ./log_parser.cpp <log file>" << endl;
		exit(-1);
	}

	// open the file for reading and check for success
	ifstream log_file;
	log_file.open(argv[1]);
	if (!log_file) {
		cerr << "File failed to open. Are you sure it exists?" << endl;
		exit(-1);
	}

	/* 
	** Okay, real talk...
	** We set up a temp_record variable of type CmdRecord to start collecting the data for the
	** record to be put into the list. If we see one the the addresses that we need, we can
	** insert the record at the end of the record loop. If it's not, then just keep moving on.
	** TODO: this might be better as a function. 
	*/
	

	// now that we're in the clear, let's define some useful variables
	string curr_field = "";
	int counter = 0;
	int field_counter = 0;
	string temp_data = "";
	string past_time = "";

	// we also have to set up a new command list, and a temporary record collector
	CmdList commands;
	CmdRecord temp_record;

	// do a getline() to remove the header and fire up the record collection loop
	std::string temp;
	getline(log_file, temp);
	while(log_file >> curr_field) {
		field_counter++;

		if (field_counter == RELTIME) {
			// we have the Rel Time field value
			temp_record.Set_RelTime(curr_field);

		} else if (field_counter == ADDRESS) {
			// we have the Address field value
			temp_record.Set_Address(curr_field);

		} else if (field_counter == DATA) {
			// we have the Data field value (this is special if it's in the address of
			// a command we want, so set it aside for later)
			temp_data = curr_field;

		} else if(field_counter == SIZE) {
			// we have the Size field value
			temp_record.Set_Size(curr_field);

		} else if(field_counter == CYCLE) {
			// we have the Cycle field value
			temp_record.Set_Cycle(curr_field);

		}

		// if the field_counter is 14, that means we've hit the end of a line. this is
		// where decision making comes in. two things can happen here: if it's not a 
		// record want (the easist), we reset the field_counter and increment the 
		// line_count. if it's a record we want, we do the above and calculate the size
		// of the data, and then enter the data collection loop.
		if (field_counter == ENDLINE) {
			if (temp_record.Get_Address() == CMD1 || 
				temp_record.Get_Address() == CMD2) {
				// set the line number and past time (which is the time for the 
				// current command)
				temp_record.Set_Line_Number(patch::to_string(line_count));
				temp_record.Set_RelTime(past_time);

				// pass the current node and the ifstream to the dataCollection 
				// function to keep this from getting cluttered
				dataCollection(&temp_record, log_file, temp_data);

				//add # of words to record
				//std::cout << temp_record.HexToDec(temp_data) / 2 << "\n";
				temp_record.Set_Total_Words(temp_record.HexToDec(temp_data) / 2);
				//std::cout << temp_record.Get_Total_Words() << "\n";

				// add it to the command list
				commands.AddRecord(temp_record);
			}
			
			// this happens every time we reach the end of a line
			past_time = temp_record.Get_RelTime();
			field_counter = 0;
			line_count++;
		}  

	}
	
	log_file.close();
	//commands.PrintList();
	commands.Display();
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x558, %rsp            # imm = 0x558
cmpl $0x2, %edi
jne 0x2893
movq %rsi, %rbx
leaq -0x578(%rbp), %r14
movq %r14, %rdi
callq 0x21c0
movq 0x8(%rbx), %rsi
pushq $0x8
popq %rdx
movq %r14, %rdi
callq 0x2120
movq -0x578(%rbp), %rax
movq -0x18(%rax), %rax
testb $0x5, -0x558(%rbp,%rax)
jne 0x28d0
leaq 0x2f8b(%rip), %rsi      # 0x5465
leaq -0x50(%rbp), %rdi
leaq -0x290(%rbp), %rdx
callq 0x2c3c
leaq 0x2f74(%rip), %rsi      # 0x5465
leaq -0x70(%rbp), %rdi
leaq -0x290(%rbp), %rdx
callq 0x2c3c
leaq 0x2f5d(%rip), %rsi      # 0x5465
leaq -0x90(%rbp), %rdi
leaq -0x290(%rbp), %rdx
callq 0x2c3c
leaq -0x30(%rbp), %rdi
callq 0x3d6c
leaq -0x290(%rbp), %rdi
callq 0x308c
leaq -0xe0(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq -0x578(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x2030
xorl %ebx, %ebx
leaq -0x578(%rbp), %r15
leaq 0x2a9e(%rip), %r12      # 0x5004
leaq -0x290(%rbp), %r13
movq %r15, %rdi
leaq -0x50(%rbp), %rsi
callq 0x2200
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x281f
leal 0x1(%rbx), %eax
movl %ebx, %ecx
addl $-0x2, %ecx
movl %eax, %ebx
cmpl $0xb, %ecx
ja 0x256d
movslq (%r12,%rcx,4), %rcx
addq %r12, %rcx
movl %eax, %ebx
jmpq *%rcx
leaq -0x1d0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x2230
movq %r13, %rdi
leaq -0x1d0(%rbp), %rbx
movq %rbx, %rsi
callq 0x32b2
movq %rbx, %rdi
callq 0x20e0
pushq $0x3
popq %rax
movl %eax, %ebx
jmp 0x256d
leaq -0x170(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x2230
movq %r13, %rdi
leaq -0x170(%rbp), %rbx
movq %rbx, %rsi
callq 0x3288
movq %rbx, %rdi
callq 0x20e0
pushq $0xa
popq %rax
movl %eax, %ebx
jmp 0x256d
leaq -0x70(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x2110
pushq $0x8
popq %rax
movl %eax, %ebx
jmp 0x256d
leaq -0x190(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x2230
movq %r13, %rdi
leaq -0x190(%rbp), %rbx
movq %rbx, %rsi
callq 0x325e
movq %rbx, %rdi
callq 0x20e0
pushq $0x9
popq %rax
movl %eax, %ebx
jmp 0x256d
leaq -0x1b0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x2230
movq %r13, %rdi
leaq -0x1b0(%rbp), %rbx
movq %rbx, %rsi
callq 0x3206
movq %rbx, %rdi
callq 0x20e0
pushq $0x7
popq %rax
movl %eax, %ebx
jmp 0x256d
leaq -0xd0(%rbp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x3214
movq %rbx, %rdi
leaq 0x2a10(%rip), %rsi      # 0x50b5
callq 0x2c77
testb %al, %al
je 0x26b8
movq %rbx, %rdi
callq 0x20e0
jmp 0x26fd
movq %r13, %rsi
leaq -0x2b0(%rbp), %r14
movq %r14, %rdi
callq 0x3214
movq %r14, %rdi
leaq 0x29ea(%rip), %rsi      # 0x50be
callq 0x2c77
movl %eax, %ebx
movq %r14, %rdi
callq 0x20e0
leaq -0xd0(%rbp), %r14
movq %r14, %rdi
callq 0x20e0
testb %bl, %bl
movq %r14, %rbx
je 0x27f0
leaq -0x150(%rbp), %rdi
leaq 0x5a8d(%rip), %rsi      # 0x8198
callq 0x2c87
movq %r13, %rdi
leaq -0x150(%rbp), %rbx
movq %rbx, %rsi
callq 0x31e4
movq %rbx, %rdi
callq 0x20e0
leaq -0x130(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x2230
movq %r13, %rdi
leaq -0x130(%rbp), %rbx
movq %rbx, %rsi
callq 0x32b2
movq %rbx, %rdi
callq 0x20e0
leaq -0x110(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x2230
movq %r13, %rdi
movq %r15, %rsi
leaq -0x110(%rbp), %rbx
movq %rbx, %rdx
callq 0x29f5
movq %rbx, %rdi
callq 0x20e0
leaq -0xb0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x2230
movq %r13, %rdi
leaq -0xb0(%rbp), %rsi
callq 0x3386
cltd
pushq $0x2
popq %rcx
idivl %ecx
movq %r13, %rdi
movl %eax, %esi
callq 0x32e4
leaq -0xb0(%rbp), %rdi
callq 0x20e0
leaq -0x370(%rbp), %rdi
movq %r13, %rsi
callq 0x2cfa
leaq -0x30(%rbp), %rdi
leaq -0x370(%rbp), %rbx
movq %rbx, %rsi
callq 0x3dbc
movq %rbx, %rdi
callq 0x2dd2
leaq -0xd0(%rbp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x32c4
leaq -0x90(%rbp), %rdi
movq %rbx, %rsi
callq 0x21e0
movq %rbx, %rdi
callq 0x20e0
incl 0x5980(%rip)            # 0x8198
xorl %ebx, %ebx
jmp 0x256d
leaq -0x578(%rbp), %rdi
callq 0x2040
leaq -0x30(%rbp), %rdi
callq 0x403c
leaq -0xf0(%rbp), %rdi
callq 0x20e0
leaq -0x290(%rbp), %rdi
callq 0x2dd2
leaq -0x30(%rbp), %rdi
callq 0x3d76
leaq -0x90(%rbp), %rdi
callq 0x20e0
leaq -0x70(%rbp), %rdi
callq 0x20e0
leaq -0x50(%rbp), %rdi
callq 0x20e0
leaq -0x578(%rbp), %rdi
callq 0x2070
xorl %eax, %eax
addq $0x558, %rsp            # imm = 0x558
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x5756(%rip), %rbx      # 0x7ff0
leaq 0x27a7(%rip), %rsi      # 0x5048
movq %rbx, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20f0
leaq 0x27ad(%rip), %rsi      # 0x5065
movq %rbx, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20f0
pushq $-0x1
popq %rdi
callq 0x21d0
movq 0x5719(%rip), %rdi      # 0x7ff0
leaq 0x27aa(%rip), %rsi      # 0x5088
callq 0x2180
movq %rax, %rdi
callq 0x20f0
jmp 0x28c8
movq %rax, %rbx
jmp 0x29ba
movq %rax, %rbx
jmp 0x29c3
movq %rax, %rbx
jmp 0x29cf
movq %rax, %rbx
jmp 0x29d8
jmp 0x290f
movq %rax, %rbx
jmp 0x29e1
movq %rax, %rbx
leaq -0xd0(%rbp), %rdi
jmp 0x2998
jmp 0x299f
movq %rax, %rbx
leaq -0x130(%rbp), %rdi
jmp 0x2998
movq %rax, %rbx
leaq -0x110(%rbp), %rdi
jmp 0x2998
movq %rax, %rbx
leaq -0x370(%rbp), %rdi
callq 0x2dd2
jmp 0x29a2
movq %rax, %rbx
leaq -0x150(%rbp), %rdi
jmp 0x2998
movq %rax, %rbx
leaq -0x190(%rbp), %rdi
jmp 0x2998
jmp 0x299f
movq %rax, %rbx
leaq -0x170(%rbp), %rdi
jmp 0x2998
movq %rax, %rbx
leaq -0x1b0(%rbp), %rdi
jmp 0x2998
movq %rax, %rbx
leaq -0x1d0(%rbp), %rdi
jmp 0x2998
jmp 0x299f
movq %rax, %rbx
leaq -0xb0(%rbp), %rdi
callq 0x20e0
jmp 0x29a2
movq %rax, %rbx
leaq -0xf0(%rbp), %rdi
callq 0x20e0
leaq -0x290(%rbp), %rdi
callq 0x2dd2
leaq -0x30(%rbp), %rdi
callq 0x3d76
leaq -0x90(%rbp), %rdi
callq 0x20e0
leaq -0x70(%rbp), %rdi
callq 0x20e0
leaq -0x50(%rbp), %rdi
callq 0x20e0
leaq -0x578(%rbp), %rdi
callq 0x2070
movq %rbx, %rdi
callq 0x22c0