// File: llefranc[P]42_webserv/srcs/server/Cgi.cpp
// Function: CGI::executeCGI()
void CGI::executeCGI()
{
	int fdOut[2];
	int fdIN[2];
	
	if (pipe(fdOut) < 0 || pipe(fdIN) < 0)
		throw StatusLine(500, REASON_500, "pipe failed in executeCGI method");
	
	pid_t pid = fork();
	
	if (!pid){
		
		// stdout is now a copy of fdOut[1] and in case post method, stdin is a copy of fdIn[0]
		dup2(fdOut[1], STDOUT_FILENO);
		close(fdOut[0]);
		close(fdOut[1]);

		dup2(fdIN[0], STDIN_FILENO);
		close(fdIN[0]);
		close(fdIN[1]);

		// change the repo into where the program is
		chdir(_path_info.first.c_str());
	
		if (execve(_args[0], _args, _envvar) < 0){
			exit(EXECVE_FAIL);
		}
	
	}
	else if (pid > 0){
		
		close(fdOut[1]);
		if (_req->getMethod() == POST){
			if (write(fdIN[1], _req->getBody().getBody().c_str(), _req->getBody().getBody().size()) < 0)
				throw StatusLine(500, REASON_500, "write failed in executeCGI method");
		}
		
		else{
			if (write(fdIN[1], _getBuffFile.c_str(), _getBuffFile.size()) < 0)
				throw StatusLine(500, REASON_500, "write failed in executeCGI method");
		}
		
		close(fdIN[1]);
		close(fdIN[0]);
		
        // Checking if execve correctly worked
        int status = 0;
        waitpid(pid, &status, 0);
        if (WIFEXITED(status) && WEXITSTATUS(status) == EXECVE_FAIL)
            throw StatusLine(500, REASON_500, "execve failed in executeCGI method");
        
		char buf[CGI_PIPE_BUFFER_SIZE + 1] = {0};
		std::string msgbody;	
		while (read(fdOut[0], buf, CGI_PIPE_BUFFER_SIZE) > 0)
		{
			msgbody += buf;
			memset(buf, 0, CGI_PIPE_BUFFER_SIZE + 1);
		}
		msgbody += buf;

		close(fdOut[0]);

		_emptyBody->setBuff(msgbody);
		
		// remove the header part of the cgi output
		_emptyBody->setSize(msgbody.size() - (msgbody.find("\r\n\r\n") + 4)); 
	}
	else{
		close(fdOut[1]); close(fdOut[0]);
		if (_req->getMethod() == POST) { close(fdIN[0]); close(fdIN[1]); }
		throw StatusLine(500, REASON_500, "fork failed executeCGI method");
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x9b0, %rsp            # imm = 0x9B0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x920(%rbp)
leaq -0x10(%rbp), %rdi
callq 0x5740
cmpl $0x0, %eax
jl 0x2024a
leaq -0x18(%rbp), %rdi
callq 0x5740
cmpl $0x0, %eax
jge 0x2030e
movb $0x1, -0x4d(%rbp)
movl $0x48, %edi
callq 0x5290
movq %rax, -0x930(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0x928(%rbp)
callq 0x58f0
movq -0x928(%rbp), %rdx
leaq 0x3990(%rip), %rsi      # 0x23c0d
leaq -0x38(%rbp), %rdi
callq 0x63e0
jmp 0x20288
movq -0x930(%rbp), %rdi
leaq 0x3812(%rip), %rdx      # 0x23aa8
movl $0x1f4, %esi            # imm = 0x1F4
leaq -0x38(%rbp), %rcx
callq 0x199d0
jmp 0x202a6
movq -0x930(%rbp), %rdi
movb $0x0, -0x4d(%rbp)
leaq 0x10ad8(%rip), %rsi     # 0x30d90
leaq -0x683f(%rip), %rdx     # 0x19a80
callq 0x58a0
jmp 0x209c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x202ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x5a08
leaq -0x39(%rbp), %rdi
callq 0x55c0
testb $0x1, -0x4d(%rbp)
jne 0x202fd
jmp 0x20309
movq -0x930(%rbp), %rdi
callq 0x53f0
jmp 0x209b9
callq 0x5190
movl %eax, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
jne 0x203a0
movl -0xc(%rbp), %edi
movl $0x1, %esi
callq 0x54f0
movl -0x10(%rbp), %edi
callq 0x59c0
movl -0xc(%rbp), %edi
callq 0x59c0
movl -0x18(%rbp), %edi
xorl %esi, %esi
callq 0x54f0
movl -0x18(%rbp), %edi
callq 0x59c0
movl -0x14(%rbp), %edi
callq 0x59c0
movq -0x920(%rbp), %rdi
addq $0x290, %rdi            # imm = 0x290
callq 0x5240
movq %rax, %rdi
callq 0x57b0
movq -0x920(%rbp), %rax
movq 0x8(%rax), %rcx
movq (%rcx), %rdi
movq 0x8(%rax), %rsi
movq (%rax), %rdx
callq 0x5890
cmpl $0x0, %eax
jge 0x2039b
movl $0xff, %edi
callq 0x5660
jmp 0x209b0
cmpl $0x0, -0x54(%rbp)
jle 0x208a3
movl -0xc(%rbp), %edi
callq 0x59c0
movq -0x920(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x174a0
cmpl $0x2, %eax
jne 0x20506
movq -0x920(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, -0x93c(%rbp)
movq 0x18(%rax), %rdi
callq 0x17470
movq %rax, %rdi
callq 0x19c90
movq %rax, %rdi
callq 0x5240
movq %rax, %rcx
movq -0x920(%rbp), %rax
movq %rcx, -0x938(%rbp)
movq 0x18(%rax), %rdi
callq 0x17470
movq %rax, %rdi
callq 0x19c90
movq %rax, %rdi
callq 0x53b0
movl -0x93c(%rbp), %edi
movq -0x938(%rbp), %rsi
movq %rax, %rdx
callq 0x51e0
cmpq $0x0, %rax
jge 0x20501
movb $0x1, -0x7a(%rbp)
movl $0x48, %edi
callq 0x5290
movq %rax, -0x950(%rbp)
leaq -0x79(%rbp), %rdi
movq %rdi, -0x948(%rbp)
callq 0x58f0
movq -0x948(%rbp), %rdx
leaq 0x37be(%rip), %rsi      # 0x23c2e
leaq -0x78(%rbp), %rdi
callq 0x63e0
jmp 0x2047b
movq -0x950(%rbp), %rdi
leaq 0x361f(%rip), %rdx      # 0x23aa8
movl $0x1f4, %esi            # imm = 0x1F4
leaq -0x78(%rbp), %rcx
callq 0x199d0
jmp 0x20499
movq -0x950(%rbp), %rdi
movb $0x0, -0x7a(%rbp)
leaq 0x108e5(%rip), %rsi     # 0x30d90
leaq -0x6a32(%rip), %rdx     # 0x19a80
callq 0x58a0
jmp 0x209c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x204df
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x5a08
leaq -0x79(%rbp), %rdi
callq 0x55c0
testb $0x1, -0x7a(%rbp)
jne 0x204f0
jmp 0x204fc
movq -0x950(%rbp), %rdi
callq 0x53f0
jmp 0x209b9
jmp 0x20639
movq -0x920(%rbp), %rdi
movl -0x14(%rbp), %eax
movl %eax, -0x95c(%rbp)
addq $0x270, %rdi            # imm = 0x270
callq 0x5240
movq -0x920(%rbp), %rdi
movq %rax, -0x958(%rbp)
addq $0x270, %rdi            # imm = 0x270
callq 0x53b0
movl -0x95c(%rbp), %edi
movq -0x958(%rbp), %rsi
movq %rax, %rdx
callq 0x51e0
cmpq $0x0, %rax
jge 0x20637
movb $0x1, -0xa2(%rbp)
movl $0x48, %edi
callq 0x5290
movq %rax, -0x970(%rbp)
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x968(%rbp)
callq 0x58f0
movq -0x968(%rbp), %rdx
leaq 0x369a(%rip), %rsi      # 0x23c2e
leaq -0xa0(%rbp), %rdi
callq 0x63e0
jmp 0x205a2
movq -0x970(%rbp), %rdi
leaq 0x34f8(%rip), %rdx      # 0x23aa8
movl $0x1f4, %esi            # imm = 0x1F4
leaq -0xa0(%rbp), %rcx
callq 0x199d0
jmp 0x205c3
movq -0x970(%rbp), %rdi
movb $0x0, -0xa2(%rbp)
leaq 0x107b8(%rip), %rsi     # 0x30d90
leaq -0x6b5f(%rip), %rdx     # 0x19a80
callq 0x58a0
jmp 0x209c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x2060f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x5a08
leaq -0xa1(%rbp), %rdi
callq 0x55c0
testb $0x1, -0xa2(%rbp)
jne 0x20626
jmp 0x20632
movq -0x970(%rbp), %rdi
callq 0x53f0
jmp 0x209b9
jmp 0x20639
movl -0x14(%rbp), %edi
callq 0x59c0
movl -0x18(%rbp), %edi
callq 0x59c0
movl $0x0, -0xa8(%rbp)
movl -0x54(%rbp), %edi
leaq -0xa8(%rbp), %rsi
xorl %edx, %edx
callq 0x5430
movl -0xa8(%rbp), %eax
andl $0x7f, %eax
cmpl $0x0, %eax
jne 0x2076b
movl -0xa8(%rbp), %eax
andl $0xff00, %eax           # imm = 0xFF00
sarl $0x8, %eax
cmpl $0xff, %eax
jne 0x2076b
movb $0x1, -0xca(%rbp)
movl $0x48, %edi
callq 0x5290
movq %rax, -0x980(%rbp)
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x978(%rbp)
callq 0x58f0
movq -0x978(%rbp), %rdx
leaq 0x3588(%rip), %rsi      # 0x23c50
leaq -0xc8(%rbp), %rdi
callq 0x63e0
jmp 0x206d6
movq -0x980(%rbp), %rdi
leaq 0x33c4(%rip), %rdx      # 0x23aa8
movl $0x1f4, %esi            # imm = 0x1F4
leaq -0xc8(%rbp), %rcx
callq 0x199d0
jmp 0x206f7
movq -0x980(%rbp), %rdi
movb $0x0, -0xca(%rbp)
leaq 0x10684(%rip), %rsi     # 0x30d90
leaq -0x6c93(%rip), %rdx     # 0x19a80
callq 0x58a0
jmp 0x209c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x20743
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x5a08
leaq -0xc9(%rbp), %rdi
callq 0x55c0
testb $0x1, -0xca(%rbp)
jne 0x2075a
jmp 0x20766
movq -0x980(%rbp), %rdi
callq 0x53f0
jmp 0x209b9
leaq -0x8d0(%rbp), %rdi
xorl %esi, %esi
movl $0x7ff, %edx            # imm = 0x7FF
callq 0x52e0
leaq -0x8f0(%rbp), %rdi
callq 0x5770
movl -0x10(%rbp), %edi
leaq -0x8d0(%rbp), %rsi
movl $0x7fe, %edx            # imm = 0x7FE
callq 0x5790
movq %rax, -0x988(%rbp)
jmp 0x207a7
movq -0x988(%rbp), %rax
cmpq $0x0, %rax
jle 0x207fb
leaq -0x8f0(%rbp), %rdi
leaq -0x8d0(%rbp), %rsi
callq 0x5520
jmp 0x207c9
leaq -0x8d0(%rbp), %rdi
xorl %esi, %esi
movl $0x7ff, %edx            # imm = 0x7FF
callq 0x52e0
jmp 0x2078a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x8f0(%rbp), %rdi
callq 0x5a08
jmp 0x209b9
leaq -0x8f0(%rbp), %rdi
leaq -0x8d0(%rbp), %rsi
callq 0x5520
jmp 0x20810
movl -0x10(%rbp), %edi
callq 0x59c0
jmp 0x2081a
movq -0x920(%rbp), %rax
movq 0x10(%rax), %rdi
leaq -0x8f0(%rbp), %rsi
callq 0x20ab0
jmp 0x20833
movq -0x920(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x990(%rbp)
leaq -0x8f0(%rbp), %rdi
movq %rdi, -0x9a0(%rbp)
callq 0x53b0
movq -0x9a0(%rbp), %rdi
movq %rax, -0x998(%rbp)
leaq 0x3406(%rip), %rsi      # 0x23c73
xorl %eax, %eax
movl %eax, %edx
callq 0x59e0
movq -0x998(%rbp), %rsi
movq -0x990(%rbp), %rdi
subq %rax, %rsi
addq $-0x4, %rsi
callq 0x19b00
jmp 0x20892
leaq -0x8f0(%rbp), %rdi
callq 0x5a08
jmp 0x209ae
movl -0xc(%rbp), %edi
callq 0x59c0
movl -0x10(%rbp), %edi
callq 0x59c0
movq -0x920(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x174a0
cmpl $0x2, %eax
jne 0x208d8
movl -0x18(%rbp), %edi
callq 0x59c0
movl -0x14(%rbp), %edi
callq 0x59c0
movb $0x1, -0x912(%rbp)
movl $0x48, %edi
callq 0x5290
movq %rax, -0x9b0(%rbp)
leaq -0x911(%rbp), %rdi
movq %rdi, -0x9a8(%rbp)
callq 0x58f0
movq -0x9a8(%rbp), %rdx
leaq 0x3367(%rip), %rsi      # 0x23c78
leaq -0x910(%rbp), %rdi
callq 0x63e0
jmp 0x2091f
movq -0x9b0(%rbp), %rdi
leaq 0x317b(%rip), %rdx      # 0x23aa8
movl $0x1f4, %esi            # imm = 0x1F4
leaq -0x910(%rbp), %rcx
callq 0x199d0
jmp 0x20940
movq -0x9b0(%rbp), %rdi
movb $0x0, -0x912(%rbp)
leaq 0x1043b(%rip), %rsi     # 0x30d90
leaq -0x6edc(%rip), %rdx     # 0x19a80
callq 0x58a0
jmp 0x209c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x20989
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x910(%rbp), %rdi
callq 0x5a08
leaq -0x911(%rbp), %rdi
callq 0x55c0
testb $0x1, -0x912(%rbp)
jne 0x209a0
jmp 0x209ac
movq -0x9b0(%rbp), %rdi
callq 0x53f0
jmp 0x209b9
jmp 0x209b0
addq $0x9b0, %rsp            # imm = 0x9B0
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x58e0
nopw %cs:(%rax,%rax)