// File: /workspace/github_cpp_makefile_star2_O2/SaadBazaz[P]RIP-Protocol-Simulation/Router.cpp
// Function: handlePacket(int const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void handlePacket(const int &client, string packet)
{
	auto vec = tokenizeData(packet, '&');
	// for (int i=0; i<vec.size(); i++){
	// 		std::cout<<vec[i]<<std::endl;
	// }


	if (vec[0] == "OK"){
		std::cout<<"Something good happened!"<<std::endl;
		return;
	}
	else if (vec[0] == "BAD"){
		std::cout<<"Oops, something went wrong..."<<std::endl;
		return;
	}


	switch (stoi(vec[0]))
	{
	case UPDATE:
	{
		// cout<<"In UPDATE..."<<endl;
		TableRow table_row(vec[3]);
		// cout<<"Made table_row..."<<endl;
		int index = findRowByFDAndID(client, table_row.identifier);

		if (index < 0)
		{

			// if match not found
			// remove all id = -1 values from table and add new table_row
			for (int i=0; i<table.size(); i++){
				if (table[i].identifier == -1){
					table.erase (table.begin() + i);
					i--;
				}
			} 

			table_row.fd = client;
			if (table_row.hop_count < 0)
			{
				table_row.hop_count = 0;
			}
			
			table.push_back(table_row);
			printTable();
			break;
		}


		if (table_row.identifier >= 0)
		{
			table[index].identifier = table_row.identifier;
		}

		// if (table_row.client_name >= 0){
		// 	table[index].client_name = table_row.client_name;
		// }

		if (table_row.status >= 0)
		{
			table[index].status = table_row.status;
		}

		if (table_row.hop_count >= 0)
		{
			table[index].hop_count = table_row.hop_count;
		}

		if (table_row.type != "")
		{
			table[index].type = table_row.type;
		}

		// if (table_row.in_use >= 0){
		table[index].in_use = table_row.in_use;
		// }

		if (table_row.send_port >= 0)
		{
			table[index].send_port = table_row.send_port;
		}

		if (table_row.receive_port >= 0)
		{
			table[index].receive_port = table_row.receive_port;
		}

		printTable();
		sendTableToAllRouters();

		break;
	}
	case ADD:
		break;

	case DELETE:
		break;

	case TABLE:{

		// auto index_vec = findAllRowsByFD(client);

		auto new_rows = deserialize(vec[3]);		


		// cout<<"New Rows - - - - - "<<endl;
		for (int i=0; i<new_rows.size(); i++){


			new_rows[i].fd = client;

			// cout<<new_rows[i].identifier<<endl;

		}
		// cout<<"- - - - - - - - - - "<<endl;



		// Clean useless data out of new_rows vector
		for (int i=0; i<table.size(); i++)
		{
			for (int j=0; j<new_rows.size(); j++){
				if (table[i] == new_rows[j] 
				or (table[i].fd == client and table[i].identifier == new_rows[j].identifier)
				or (table[i].identifier == new_rows[j].identifier and table[i].hop_count == 0)
				or (new_rows[j].hop_count >= 15)
				//  or new_rows[j].identifier == -1 or new_rows[j].identifier == port
				)

				{
					new_rows.erase(new_rows.begin() + j);
					j--;	
				}
			}
		}

		for (int j=0; j<new_rows.size(); j++){
			if (new_rows[j].identifier == -1 or new_rows[j].identifier == port){
				new_rows.erase(new_rows.begin() + j);
				j--;
			}
		}


		// cout<<"New Rows [CLEANED] - - - - - "<<endl;
		// for (int i=0; i<new_rows.size(); i++){
		// 	cout<<new_rows[i].identifier<<endl;
		// }
		// cout<<"- - - - - - - - - - "<<endl;



		// Add data from new_rows into table
		for (int i=0; i<new_rows.size(); i++){
				new_rows[i].hop_count ++;
				new_rows[i].fd = client;
				table.push_back(new_rows[i]);
		}

		// for (int i=0; i<new_rows.size(); i++){
		// 	if (new_rows[i].identifier != port)
		// 		table.push_back(new_rows[i]);
		// }

		printTable();
		sendTableToAllRouters(client);  //ignore this client when sending table to routers
		break;
	}

	case MESSAGE:
	{
		int index = findRowByID_MinHopCount(stoi(vec[2]));

		if (index < 0)
		{
			break;
		}

		if (vec.size() == 4){
			packet += '&';
			packet += to_string(port);
		}
		else {
			packet += ',';
			packet += to_string(port);			
		}

		// Forward packet to appropriate socket
		send(table[index].fd, packet.c_str(), strlen(packet.c_str()), 0);
		break;
	}
	default:
		break;
	}
	// if (vec[0] == UPDATE){
	// 	if ()

	// }
	// send(client, "OK", 2, 0); //Reply message to client
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x98(%rsp), %r15
movq %r15, %rdi
callq 0x22c0
leaq 0x40(%rsp), %rdi
pushq $0x26
popq %rdx
movq %r15, %rsi
callq 0x251c
leaq 0x98(%rsp), %rdi
callq 0x20f0
movq 0x40(%rsp), %rdi
leaq 0x2000(%rip), %rsi      # 0x5088
callq 0x441a
testb %al, %al
je 0x309a
leaq 0x1ff3(%rip), %rsi      # 0x508b
jmp 0x30b6
movq 0x40(%rsp), %rdi
leaq 0x1ffe(%rip), %rsi      # 0x50a4
callq 0x441a
testb %al, %al
je 0x30e6
leaq 0x1ff2(%rip), %rsi      # 0x50a8
movq 0x4f0b(%rip), %rdi      # 0x7fc8
callq 0x2220
movq %rax, %rdi
callq 0x2100
leaq 0x40(%rsp), %rdi
callq 0x3cf2
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x40(%rsp), %rdi
pushq $0xa
popq %rdx
xorl %esi, %esi
callq 0x4427
cmpl $0x1, %eax
je 0x3275
cmpl $0x4, %eax
je 0x3212
cmpl $0x2, %eax
jne 0x30ca
movq 0x40(%rsp), %rsi
addq $0x60, %rsi
leaq 0x78(%rsp), %rdi
callq 0x22c0
movq %rsp, %rdi
leaq 0x78(%rsp), %rsi
pushq $0x2c
popq %rdx
callq 0x41a4
leaq 0x78(%rsp), %rdi
callq 0x20f0
movl (%rbx), %edi
movl (%rsp), %ebp
movl %ebp, %esi
callq 0x2d4f
testl %eax, %eax
js 0x3415
movl %eax, %r14d
testl %ebp, %ebp
js 0x3165
movq 0x50ad(%rip), %rax      # 0x8208
movq %r14, %rcx
shlq $0x6, %rcx
movl %ebp, (%rax,%rcx)
movzwl 0x8(%rsp), %eax
testw %ax, %ax
js 0x3182
movq 0x5092(%rip), %rcx      # 0x8208
movq %r14, %rdx
shlq $0x6, %rdx
movw %ax, 0x8(%rcx,%rdx)
movl 0xc(%rsp), %eax
testl %eax, %eax
js 0x319c
movq 0x5077(%rip), %rcx      # 0x8208
movq %r14, %rdx
shlq $0x6, %rdx
movl %eax, 0xc(%rcx,%rdx)
leaq 0x10(%rsp), %rbx
leaq 0x1ec7(%rip), %rsi      # 0x506f
movq %rbx, %rdi
callq 0x4449
testb %al, %al
je 0x31d2
movq 0x504d(%rip), %rax      # 0x8208
movq %r14, %rcx
shlq $0x6, %rcx
leaq (%rax,%rcx), %rdi
addq $0x10, %rdi
movq %rbx, %rsi
callq 0x2130
movb 0x30(%rsp), %cl
movq 0x502b(%rip), %rdx      # 0x8208
shlq $0x6, %r14
leaq (%rdx,%r14), %rax
movb %cl, 0x30(%rdx,%r14)
movl 0x34(%rsp), %ecx
testl %ecx, %ecx
js 0x31f5
movl %ecx, 0x34(%rax)
movl 0x38(%rsp), %ecx
testl %ecx, %ecx
js 0x3200
movl %ecx, 0x38(%rax)
callq 0x2b94
pushq $-0x1
popq %rdi
callq 0x2e91
jmp 0x347c
movq 0x40(%rsp), %rdi
addq $0x40, %rdi
pushq $0xa
popq %rdx
xorl %esi, %esi
callq 0x4427
movl %eax, %edi
callq 0x2cda
testl %eax, %eax
js 0x30ca
movl %eax, %ebx
movq 0x48(%rsp), %rax
subq 0x40(%rsp), %rax
cmpq $0x80, %rax
jne 0x348b
pushq $0x26
popq %rsi
movq %r14, %rdi
callq 0x21f0
movl 0x4fc3(%rip), %esi      # 0x8220
movq %rsp, %rdi
callq 0x4333
movq %rsp, %rsi
movq %r14, %rdi
callq 0x23a0
jmp 0x34af
movq 0x40(%rsp), %rsi
addq $0x60, %rsi
leaq 0x58(%rsp), %rdi
callq 0x22c0
movq %rsp, %rdi
leaq 0x58(%rsp), %rsi
callq 0x2706
leaq 0x58(%rsp), %rdi
callq 0x20f0
movq (%rsp), %rsi
movq 0x8(%rsp), %rax
movq %rax, %rcx
subq %rsi, %rcx
sarq $0x6, %rcx
leaq 0x4(%rsi), %rdx
subq $0x1, %rcx
jb 0x32c6
movl (%rbx), %edi
movl %edi, (%rdx)
addq $0x40, %rdx
jmp 0x32b6
xorl %r15d, %r15d
movq %rsp, %r14
movq 0x4f3d(%rip), %rcx      # 0x8210
subq 0x4f2e(%rip), %rcx      # 0x8208
sarq $0x6, %rcx
xorl %ebp, %ebp
cmpq %r15, %rcx
jbe 0x3373
movq %r15, %r12
shlq $0x6, %r12
movslq %ebp, %r13
movq %rax, %rcx
subq %rsi, %rcx
sarq $0x6, %rcx
cmpq %r13, %rcx
jbe 0x336b
movq 0x4eff(%rip), %rdi      # 0x8208
addq %r12, %rdi
shlq $0x6, %r13
addq %r13, %rsi
callq 0x25df
movq (%rsp), %rsi
testb %al, %al
jne 0x3351
movq 0x4ee1(%rip), %rax      # 0x8208
movl (%rax,%r12), %ecx
movl 0x4(%rax,%r12), %edi
movl (%rsi,%r13), %edx
cmpl (%rbx), %edi
jne 0x333c
cmpl %edx, %ecx
je 0x3351
cmpl %edx, %ecx
jne 0x3349
addq %r12, %rax
cmpl $0x0, 0xc(%rax)
je 0x3351
cmpl $0xf, 0xc(%rsi,%r13)
jl 0x3362
addq %r13, %rsi
movq %r14, %rdi
callq 0x4444
decl %ebp
movq (%rsp), %rsi
incl %ebp
movq 0x8(%rsp), %rax
jmp 0x32f0
incq %r15
jmp 0x32cc
movq %rsp, %r14
movslq %ebp, %rcx
movq %rax, %rdx
subq %rsi, %rdx
sarq $0x6, %rdx
cmpq %rcx, %rdx
jbe 0x33b6
shlq $0x6, %rcx
movl (%rsi,%rcx), %edx
cmpl $-0x1, %edx
je 0x339c
cmpl 0x4e86(%rip), %edx      # 0x8220
jne 0x33b2
addq %rcx, %rsi
movq %r14, %rdi
callq 0x4444
decl %ebp
movq (%rsp), %rsi
movq 0x8(%rsp), %rax
incl %ebp
jmp 0x3376
xorl %r15d, %r15d
leaq 0x4e48(%rip), %r14      # 0x8208
xorl %r12d, %r12d
subq %rsi, %rax
sarq $0x6, %rax
cmpq %r12, %rax
jbe 0x33fc
incl 0xc(%rsi,%r15)
leaq (%rsi,%r15), %rax
movl (%rbx), %ecx
movl %ecx, 0x4(%rsi,%r15)
movq %r14, %rdi
movq %rax, %rsi
callq 0x42e6
incq %r12
movq (%rsp), %rsi
movq 0x8(%rsp), %rax
addq $0x40, %r15
jmp 0x33c3
callq 0x2b94
movl (%rbx), %edi
callq 0x2e91
movq %rsp, %rdi
callq 0x4312
jmp 0x30ca
xorl %ebp, %ebp
leaq 0x4dea(%rip), %r14      # 0x8208
movslq %ebp, %rax
movq 0x4de8(%rip), %rcx      # 0x8210
movq 0x4dd9(%rip), %rsi      # 0x8208
subq %rsi, %rcx
sarq $0x6, %rcx
cmpq %rax, %rcx
jbe 0x3456
shlq $0x6, %rax
cmpl $-0x1, (%rsi,%rax)
jne 0x3452
addq %rax, %rsi
movq %r14, %rdi
callq 0x4444
decl %ebp
incl %ebp
jmp 0x341e
movl (%rbx), %eax
movl %eax, 0x4(%rsp)
cmpl $0x0, 0xc(%rsp)
jns 0x3468
andl $0x0, 0xc(%rsp)
leaq 0x4d99(%rip), %rdi      # 0x8208
movq %rsp, %rsi
callq 0x42e6
callq 0x2b94
leaq 0x10(%rsp), %rdi
callq 0x20f0
jmp 0x30ca
pushq $0x2c
popq %rsi
movq %r14, %rdi
callq 0x21f0
movl 0x4d84(%rip), %esi      # 0x8220
movq %rsp, %rdi
callq 0x4333
movq %rsp, %rsi
movq %r14, %rdi
callq 0x23a0
movq %rsp, %rdi
callq 0x20f0
movl %ebx, %eax
movq 0x4d48(%rip), %rcx      # 0x8208
shlq $0x6, %rax
movl 0x4(%rcx,%rax), %ebx
movq (%r14), %r14
movq %r14, %rdi
callq 0x20d0
movl %ebx, %edi
movq %r14, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x2110
jmp 0x30ca
jmp 0x34e9
movq %rax, %rbx
movq %rsp, %rdi
jmp 0x351b
jmp 0x3536
jmp 0x3536
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
jmp 0x351b
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
jmp 0x351b
jmp 0x3536
jmp 0x3536
jmp 0x353d
jmp 0x3536
jmp 0x3513
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x20f0
jmp 0x3548
jmp 0x353d
movq %rax, %rbx
leaq 0x98(%rsp), %rdi
callq 0x20f0
jmp 0x3552
movq %rax, %rbx
jmp 0x3548
jmp 0x353d
movq %rax, %rbx
movq %rsp, %rdi
callq 0x4312
leaq 0x40(%rsp), %rdi
callq 0x3cf2
movq %rbx, %rdi
callq 0x2360