// File: Cristian-Castillo[P]Multithreaded-HTTP-Server/./httpserver_definitions.cpp
// Function: f_make_copy(char*, int, int)
void f_make_copy(char *file_name, int content_length, int clientSocket){

    /* copy status 0 == file failed to open, status 1 == file opened succesfully */
    int copy1_status, copy2_status, copy3_status;
    copy1_status = copy2_status = copy3_status = 1;  

    ssize_t write_bytes = 0;
    ssize_t check_bytes_recv;
    int get_length = content_length;

    char *buff = (char*)malloc(get_length*sizeof(char*));

/* ----------------------------------------(FILE COPY 1/3) open phase------------------------------------------------- */  
    
    /* checking if copy1 directory exists, if not, we create it */
    struct stat st;
    char dirName[] = "copy";
    char dirCopy1[5];
    strcpy(dirCopy1 ,dirName);
    strcat(dirCopy1, "1");
    if(stat("copy1", &st) == -1){
        mkdir("copy1", 0700);
    }

    /* opening the file in diretory copy1*/
    char path_with_name1[20]; 
    strcpy (path_with_name1,"copy1/");
    strcat (path_with_name1, file_name);
    int file_copy1 = open(path_with_name1, O_CREAT | O_RDWR, 0664);
    
/* -------------------------(FILE COPY 1/3 ) checking length of file to see if == orginal size -----------------------*/

    /* if failed to open, means permission issue, so copy_status goes from 1 to 0 */
    if(file_copy1 == -1){      
        copy1_status = 0;
        close(file_copy1);
    }
    /* if file opened sucessfully */
    else{
        /* write to file in ./copy1 directory */
        write_bytes = 0;
        lseek(file_copy1, 0*sizeof(char), SEEK_SET); //points the pointer of read to the first character (beginning) of the file
        while((check_bytes_recv = read(clientSocket,buff,get_length)) >= 0){
            write_bytes += write(file_copy1,buff,check_bytes_recv);
            if(write_bytes == get_length)break;
        }
        memset(buff, 0, get_length);
    }
/*------------------------------------------ (FILE COPY 1/3 ) DONE ----------------------------------------------------*/
/*-------------------------------------------(COPY FILE 2/3 start) ----------------------------------------------------*/

    char dirCopy2[5];
    strcpy(dirCopy2 ,dirName);
    strcat(dirCopy2, "2");
    if(stat("copy2", &st) == -1){
        mkdir("copy2", 0700);
    }

    char path_with_name2[20]; 

    strcpy (path_with_name2,"copy2/");

    strcat (path_with_name2, file_name);

    int file_copy2 = open(path_with_name2, O_CREAT | O_RDWR, 0664);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    write_bytes = 0;

    if(file_copy2 == -1){
        copy2_status = 0;
        close(file_copy2);
    }
    else{
        /* copy file from ./copy1 directory into ./copy2 directory */
        lseek(file_copy1, 0*sizeof(char), SEEK_SET);
        while((check_bytes_recv = read(file_copy1,buff,get_length)) >= 0){
            write_bytes += write(file_copy2,buff,check_bytes_recv);
            if(write_bytes == get_length)break;
        }
        close(file_copy2);
        memset(buff, 0, get_length);
    }

////////////////////////////////////////////////////////////// (COPY FILE 3/3 START) ///////////////////////////////////////////////////////


    char dirCopy3[5];
    strcpy(dirCopy3 ,dirName);
    strcat(dirCopy3, "3");
    if(stat("copy3", &st) == -1){
        mkdir("copy3", 0700);
    }

    char path_with_name3[20]; 

    strcpy (path_with_name3,"copy3/");

    strcat (path_with_name3, file_name);

    int file_copy3 = open(path_with_name3, O_CREAT | O_RDWR, 0664);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    write_bytes = 0;

    if(file_copy3 == -1){
        copy3_status = 0;
        close(file_copy3);
    }
    else{

        /* copy file from ./copy1 directory into ./copy3 directory */
        lseek(file_copy1, 0*sizeof(char), SEEK_SET);

        while((check_bytes_recv = read(file_copy1,buff,get_length)) >= 0){
            write_bytes += write(file_copy3,buff,check_bytes_recv);
            if(write_bytes == get_length)break;
        }
        close(file_copy3);
        free(buff);
    }
    close(file_copy1);

    /* 3 == 201 OK ,  2 == 201 OK , 1 == 500 error, 0 == 500 error */
    int creation_results = copy1_status + copy2_status + copy3_status; 
    if(creation_results >= 2){  /* if 2 more 3 files were sucesffully written */
        f_client_req_created(clientSocket);
    }
    else if(creation_results == 0 || creation_results == 1){    /* if 0 or 1 files were sucesfully written */
        f_void_intr_error(clientSocket);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movl $0x1, -0x1c(%rbp)
movl $0x1, -0x18(%rbp)
movl $0x1, -0x14(%rbp)
movq $0x0, -0x28(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x34(%rbp)
movslq -0x34(%rbp), %rdi
shlq $0x3, %rdi
callq 0x5640
movq %rax, -0x40(%rbp)
movl 0x2ed91(%rip), %eax     # 0x357c0
movl %eax, -0xd5(%rbp)
movb 0x2ed89(%rip), %al      # 0x357c4
movb %al, -0xd1(%rbp)
leaq -0xda(%rbp), %rdi
leaq -0xd5(%rbp), %rsi
callq 0x5450
leaq -0xda(%rbp), %rdi
leaq 0x2ed5c(%rip), %rsi     # 0x357be
callq 0x5820
leaq 0x2ed6e(%rip), %rdi     # 0x357dc
leaq -0xd0(%rbp), %rsi
callq 0x5430
cmpl $-0x1, %eax
jne 0x6a90
leaq 0x2ed56(%rip), %rdi     # 0x357dc
movl $0x1c0, %esi            # imm = 0x1C0
callq 0x5210
leaq -0xf0(%rbp), %rdi
leaq 0x2ed27(%rip), %rsi     # 0x357c5
callq 0x5450
leaq -0xf0(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x5820
leaq -0xf0(%rbp), %rdi
movl $0x42, %esi
movl $0x1b4, %edx            # imm = 0x1B4
movb $0x0, %al
callq 0x5380
movl %eax, -0xf4(%rbp)
cmpl $-0x1, -0xf4(%rbp)
jne 0x6aee
movl $0x0, -0x14(%rbp)
movl -0xf4(%rbp), %edi
callq 0x58b0
jmp 0x6b5c
movq $0x0, -0x28(%rbp)
movl -0xf4(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x5880
movl -0x10(%rbp), %edi
movq -0x40(%rbp), %rsi
movslq -0x34(%rbp), %rdx
callq 0x56b0
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
jl 0x6b4d
movl -0xf4(%rbp), %edi
movq -0x40(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x5170
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
cmpq %rcx, %rax
jne 0x6b4b
jmp 0x6b4d
jmp 0x6b07
movq -0x40(%rbp), %rdi
movslq -0x34(%rbp), %rdx
xorl %esi, %esi
callq 0x5260
leaq -0xf9(%rbp), %rdi
leaq -0xd5(%rbp), %rsi
callq 0x5450
leaq -0xf9(%rbp), %rdi
leaq 0x2f3e8(%rip), %rsi     # 0x35f65
callq 0x5820
leaq 0x2ec93(%rip), %rdi     # 0x3581c
leaq -0xd0(%rbp), %rsi
callq 0x5430
cmpl $-0x1, %eax
jne 0x6bab
leaq 0x2ec7b(%rip), %rdi     # 0x3581c
movl $0x1c0, %esi            # imm = 0x1C0
callq 0x5210
leaq -0x110(%rbp), %rdi
leaq 0x2ec13(%rip), %rsi     # 0x357cc
callq 0x5450
leaq -0x110(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x5820
leaq -0x110(%rbp), %rdi
movl $0x42, %esi
movl $0x1b4, %edx            # imm = 0x1B4
movb $0x0, %al
callq 0x5380
movl %eax, -0x114(%rbp)
movq $0x0, -0x28(%rbp)
cmpl $-0x1, -0x114(%rbp)
jne 0x6c11
movl $0x0, -0x18(%rbp)
movl -0x114(%rbp), %edi
callq 0x58b0
jmp 0x6c85
movl -0xf4(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x5880
movl -0xf4(%rbp), %edi
movq -0x40(%rbp), %rsi
movslq -0x34(%rbp), %rdx
callq 0x56b0
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
jl 0x6c6b
movl -0x114(%rbp), %edi
movq -0x40(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x5170
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
cmpq %rcx, %rax
jne 0x6c69
jmp 0x6c6b
jmp 0x6c22
movl -0x114(%rbp), %edi
callq 0x58b0
movq -0x40(%rbp), %rdi
movslq -0x34(%rbp), %rdx
xorl %esi, %esi
callq 0x5260
leaq -0x119(%rbp), %rdi
leaq -0xd5(%rbp), %rsi
callq 0x5450
leaq -0x119(%rbp), %rdi
leaq 0x2f2c3(%rip), %rsi     # 0x35f69
callq 0x5820
leaq 0x2ebaa(%rip), %rdi     # 0x3585c
leaq -0xd0(%rbp), %rsi
callq 0x5430
cmpl $-0x1, %eax
jne 0x6cd4
leaq 0x2eb92(%rip), %rdi     # 0x3585c
movl $0x1c0, %esi            # imm = 0x1C0
callq 0x5210
leaq -0x130(%rbp), %rdi
leaq 0x2eaf1(%rip), %rsi     # 0x357d3
callq 0x5450
leaq -0x130(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x5820
leaq -0x130(%rbp), %rdi
movl $0x42, %esi
movl $0x1b4, %edx            # imm = 0x1B4
movb $0x0, %al
callq 0x5380
movl %eax, -0x134(%rbp)
movq $0x0, -0x28(%rbp)
cmpl $-0x1, -0x134(%rbp)
jne 0x6d3a
movl $0x0, -0x1c(%rbp)
movl -0x134(%rbp), %edi
callq 0x58b0
jmp 0x6da8
movl -0xf4(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x5880
movl -0xf4(%rbp), %edi
movq -0x40(%rbp), %rsi
movslq -0x34(%rbp), %rdx
callq 0x56b0
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
jl 0x6d94
movl -0x134(%rbp), %edi
movq -0x40(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x5170
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
cmpq %rcx, %rax
jne 0x6d92
jmp 0x6d94
jmp 0x6d4b
movl -0x134(%rbp), %edi
callq 0x58b0
movq -0x40(%rbp), %rdi
callq 0x5560
movl -0xf4(%rbp), %edi
callq 0x58b0
movl -0x14(%rbp), %eax
addl -0x18(%rbp), %eax
addl -0x1c(%rbp), %eax
movl %eax, -0x138(%rbp)
cmpl $0x2, -0x138(%rbp)
jl 0x6dd5
movl -0x10(%rbp), %edi
callq 0x68a0
jmp 0x6df1
cmpl $0x0, -0x138(%rbp)
je 0x6de7
cmpl $0x1, -0x138(%rbp)
jne 0x6def
movl -0x10(%rbp), %edi
callq 0x64a0
jmp 0x6df1
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
nopw (%rax,%rax)