// File: /workspace/github_cpp_makefile_star2_O3/sanaa-khan[P]mini-linux-shell/gbsh.cpp
// Function: listDirectory(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>)
void listDirectory(vector<string> tokens) {

	string temp, filename;

	// detecting if output has to be redirected to a file
	if (tokens.size() > 1) {
		if (tokens[1].size() == 1 and tokens[1][0] == '>') {
			if (tokens.size() == 2) {
				cout << "\033[1;31m" << "Error: ";
				cout << "\033[0;38m" << "Output file not provided.\n";
				return;
			}

			else if (tokens.size() == 3) {
				temp = ".";
				filename = tokens[2];
				oRedirect = true;
			}
			
			else {
				cout << "\033[1;31m" << "Error: ";
				cout << "\033[0;38m" << "Too many arguments.\n";
				return;
			}
		}

		else if (tokens.size() == 2)
			temp = tokens[1];

		else if (tokens.size() > 2) {
			if (tokens[2].size() == 1 and tokens[2][0] == '>') {
				if (tokens.size() == 3) {
					cout << "\033[1;31m" << "Error: ";
					cout << "\033[0;38m" << "Output file not provided.\n";
					return;
				}

				else if (tokens.size() == 4) {
					temp = tokens[1];
					filename = tokens[3];
					oRedirect = true;
				}

				else {
					cout << "\033[1;31m" << "Error: ";
					cout << "\033[0;38m" << "Too many arguments.\n";
					return;
				}
			}

			else {
				cout << "\033[1;31m" << "Error: ";
				cout << "\033[0;38m" << "Too many arguments.\n";
				return;
			}
		}
	}

	else
		temp = "."; // in the case of just "ls" command i.e no directory mentioned

	// output redirection
	if (oRedirect) {
		int file_desc = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0777);
		output = dup(1);

		close(1);
		dup(file_desc);
		close(file_desc);
	}
	
	if (tokens.size() > 4) {
		cout << "\033[1;31m" << "Error: ";
		cout << "\033[0;38m" << "Too many arguments.\n";
		return;
	}

	const char* path;
	path = temp.c_str();

	DIR* directory = NULL;
	dirent* current = NULL;
	unsigned int type;
	unsigned short length;
	char *name;

	directory = opendir(path);

	if (directory != NULL) {
		current = readdir(directory);
		
		while (current != NULL) {
			type = current->d_type;
			length = current->d_reclen;

			name = new char[length];

			strcpy(name, current->d_name);

			if ( (name[0] == '.' and name[1] == '\0') or (name[0] == '.' and name[1] == '.' and name[2] == '\0') ) {
				// do nothing in the case of '.' or ".."
			}

			else
			{
				switch (type) {
					case 4:
						if (oRedirect)
							cout << name << "\t";
						else
							cout << "\033[1;34m" << name << "\033[0m" << "\t";
						break;
					case 8:
						if (oRedirect)
							cout << name << "\t";
						else
							cout << "\033[24;37m" << name << "\033[0m" << "\t";
						break;
					default:
						cout << name << "\t";
				}
			}
			

			delete []name;
			current = readdir(directory);
		}

		closedir(directory);
		cout << "\n";

		if (oRedirect) {
			fflush(stdout); 

			dup2(output, 1);
			close(output);

			oRedirect = false;
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %rbx
leaq 0x18(%rsp), %r15
movq %r15, -0x10(%r15)
xorl %eax, %eax
movq %rax, -0x8(%r15)
movb %al, (%r15)
leaq 0x38(%rsp), %r14
movq %r14, -0x10(%r14)
movq %rax, -0x8(%r14)
movb %al, (%r14)
movq (%rdi), %rcx
movq 0x8(%rdi), %rdx
subq %rcx, %rdx
movq %rdx, %rax
sarq $0x5, %rax
cmpq $0x2, %rax
jb 0x2c85
leaq 0x20(%rcx), %rsi
cmpq $0x1, 0x28(%rcx)
jne 0x2ca5
movq (%rsi), %rdi
cmpb $0x3e, (%rdi)
jne 0x2ca5
cmpq $0x2, %rax
je 0x2ce2
cmpq $0x3, %rax
jne 0x2dc3
movl $0x40, %r14d
leaq 0x2448(%rip), %rcx      # 0x50b4
leaq 0x8(%rsp), %rdi
movl $0x1, %r8d
xorl %esi, %esi
xorl %edx, %edx
callq 0x22b0
jmp 0x2d4b
leaq 0x2428(%rip), %rcx      # 0x50b4
leaq 0x8(%rsp), %rdi
movl $0x1, %r8d
xorl %esi, %esi
xorl %edx, %edx
callq 0x22b0
jmp 0x2d62
cmpq $0x40, %rdx
jne 0x2cba
leaq 0x8(%rsp), %rdi
callq 0x20c0
jmp 0x2d62
cmpq $0x1, 0x48(%rcx)
jne 0x2dc3
movq 0x40(%rcx), %rcx
cmpb $0x3e, (%rcx)
jne 0x2dc3
cmpq $0x4, %rax
je 0x2d3b
cmpq $0x3, %rax
jne 0x2dc3
movq 0x42df(%rip), %rdi      # 0x6fc8
leaq 0x2391(%rip), %rsi      # 0x5081
movl $0x7, %edx
callq 0x21b0
movq 0x42c7(%rip), %rdi      # 0x6fc8
leaq 0x2381(%rip), %rsi      # 0x5089
movl $0x7, %edx
callq 0x21b0
movq 0x42af(%rip), %rdi      # 0x6fc8
leaq 0x2371(%rip), %rsi      # 0x5091
movl $0x7, %edx
callq 0x21b0
movl $0x1a, %edx
leaq 0x2363(%rip), %rsi      # 0x5099
jmp 0x2e17
movl $0x60, %r14d
leaq 0x8(%rsp), %rdi
callq 0x20c0
addq (%rbx), %r14
leaq 0x28(%rsp), %rdi
movq %r14, %rsi
callq 0x20c0
movb $0x1, 0x445e(%rip)      # 0x71c0
cmpb $0x1, 0x4457(%rip)      # 0x71c0
jne 0x2dab
movq 0x28(%rsp), %rdi
movl $0x241, %esi            # imm = 0x241
movl $0x1ff, %edx            # imm = 0x1FF
xorl %eax, %eax
callq 0x20e0
movl %eax, %ebp
movl $0x1, %edi
callq 0x2280
movl %eax, 0x4425(%rip)      # 0x71b8
movl $0x1, %edi
callq 0x2320
movl %ebp, %edi
callq 0x2280
movl %ebp, %edi
callq 0x2320
movq 0x8(%rbx), %rax
subq (%rbx), %rax
cmpq $0x81, %rax
leaq 0x38(%rsp), %r14
jb 0x2e60
movq 0x41fe(%rip), %rdi      # 0x6fc8
leaq 0x22b0(%rip), %rsi      # 0x5081
movl $0x7, %edx
callq 0x21b0
movq 0x41e6(%rip), %rdi      # 0x6fc8
leaq 0x22a0(%rip), %rsi      # 0x5089
movl $0x7, %edx
callq 0x21b0
movq 0x41ce(%rip), %rdi      # 0x6fc8
leaq 0x2290(%rip), %rsi      # 0x5091
movl $0x7, %edx
callq 0x21b0
movl $0x14, %edx
leaq 0x229f(%rip), %rsi      # 0x50b6
movq 0x41aa(%rip), %rdi      # 0x6fc8
callq 0x21b0
movq 0x28(%rsp), %rdi
cmpq %r14, %rdi
je 0x2e3a
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x21a0
movq 0x8(%rsp), %rdi
cmpq %r15, %rdi
je 0x2e51
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21a0
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%rsp), %rdi
callq 0x2260
testq %rax, %rax
je 0x2e23
movq %rax, %rbx
movq %rax, %rdi
callq 0x2290
movq %rax, %r13
movq 0x4144(%rip), %r14      # 0x6fc8
leaq 0x2240(%rip), %r15      # 0x50cb
testq %r13, %r13
je 0x2f7d
movzbl 0x12(%r13), %ebp
movzwl 0x10(%r13), %edi
callq 0x2030
movq %rax, %r12
addq $0x13, %r13
movq %rax, %rdi
movq %r13, %rsi
callq 0x2160
cmpb $0x2e, (%r12)
jne 0x2edb
movzbl 0x1(%r12), %eax
testl %eax, %eax
je 0x2f65
cmpl $0x2e, %eax
jne 0x2edb
cmpb $0x0, 0x2(%r12)
je 0x2f65
cmpl $0x8, %ebp
je 0x2f0a
cmpl $0x4, %ebp
jne 0x2efa
movl $0x7, %edx
cmpb $0x1, 0x42cf(%rip)      # 0x71c0
leaq 0x21d5(%rip), %rsi      # 0x50cd
jne 0x2f1f
movq %r12, %rdi
callq 0x2090
movq %rax, %r13
movq %r12, %rsi
jmp 0x2f4a
movl $0x8, %edx
cmpb $0x0, 0x42aa(%rip)      # 0x71c0
leaq 0x21b8(%rip), %rsi      # 0x50d5
jne 0x2efa
movq %r14, %rdi
callq 0x21b0
movq %r12, %rdi
callq 0x2090
movl $0x4, %r13d
movq %r14, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x21b0
leaq 0x20e0(%rip), %rsi      # 0x502a
movq %r14, %rdi
movq %r13, %rdx
callq 0x21b0
movl $0x1, %edx
movq %r14, %rdi
movq %r15, %rsi
callq 0x21b0
movq %r12, %rdi
callq 0x2210
movq %rbx, %rdi
callq 0x2290
movq %rax, %r13
jmp 0x2e8b
movq %rbx, %rdi
callq 0x22c0
movq 0x403c(%rip), %rdi      # 0x6fc8
leaq 0x21b6(%rip), %rsi      # 0x5149
movl $0x1, %edx
leaq 0x18(%rsp), %r15
leaq 0x38(%rsp), %r14
callq 0x21b0
cmpb $0x1, 0x4212(%rip)      # 0x71c0
jne 0x2e23
movq 0x3fed(%rip), %rax      # 0x6fa8
movq (%rax), %rdi
callq 0x21c0
movl 0x41ef(%rip), %edi      # 0x71b8
movl $0x1, %esi
callq 0x2150
movl 0x41df(%rip), %edi      # 0x71b8
callq 0x2320
movb $0x0, 0x41db(%rip)      # 0x71c0
jmp 0x2e23
jmp 0x2ff0
jmp 0x2ff0
jmp 0x2ff0
movq %rax, %rbx
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x300f
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x21a0
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x302b
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x21a0
movq %rbx, %rdi
callq 0x22f0