// File: dmonaldo[P]simple-network-file-system/FileSys.cpp
// Function: FileSys::mkdir(char const*)
void FileSys::mkdir(const char *name)
{
  char buffer[1024];
  bool error = false;

  dirblock_t curr_block_ptr;
  char file_name[MAX_FNAME_SIZE + 1];
  char curr_file_name[MAX_FNAME_SIZE + 1];
  strcpy(file_name, name);

  bfs.read_block(curr_dir, (void*)&curr_block_ptr);
  if(!error){
    for (unsigned int i = 0; i < MAX_DIR_ENTRIES; i++){
      strcpy(curr_file_name, curr_block_ptr.dir_entries[i].name);
      if (strcmp(curr_file_name, file_name) == 0){
        strcpy(buffer, "502: File exists\r\n");
        error = true;
      }
    }
  }
  if(!error){
    if(strlen(name) > MAX_FNAME_SIZE +1){
      strcpy(buffer, "504: File name is too long\r\n");
      error = true;
    }
  }

  // make new free block
  short block_num = bfs.get_free_block();
  if (block_num == 0){
    block_num = bfs.get_free_block();
    if (block_num == 0){
      if(!error){
        strcpy(buffer, "505: Disk is full\r\n");
        error = true;
      }
    }
  }

  if(!error){
    if (curr_block_ptr.num_entries == MAX_DIR_ENTRIES){
      strcpy(buffer, "506: Directory is full\r\n");
      error = true;
    }
  }

  //fill new directory block_num to hold 0 to show blocks are unused
  if(!error){
    dirblock_t new_block;
    new_block.magic = DIR_MAGIC_NUM;
    new_block.num_entries = 0;
    for (int i = 0; i < MAX_DIR_ENTRIES; i++){
      new_block.dir_entries[i].block_num = 0;
      new_block.dir_entries[i].name[0] = '\0';
    }
    bfs.write_block(block_num, (void*)&new_block);
    strcpy(buffer, "200 OK\r\nLength: 0\r\n\r\n");

    strcat(buffer, file_name);
    strcpy(curr_block_ptr.dir_entries[curr_block_ptr.num_entries].name,
           file_name);
    curr_block_ptr.dir_entries[curr_block_ptr.num_entries].block_num =
      block_num;
    curr_block_ptr.num_entries++;

    bfs.write_block(curr_dir, (void*)&curr_block_ptr);
  }
  send(fs_sock, buffer, sizeof(buffer), 0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x540, %rsp            # imm = 0x540
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x540(%rbp)
movb $0x0, -0x411(%rbp)
leaq -0x49e(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3320
movq -0x540(%rbp), %rax
leaq -0x494(%rbp), %rdx
movq %rax, %rdi
movswl 0x4(%rax), %esi
callq 0x3c20
testb $0x1, -0x411(%rbp)
jne 0x40a6
movl $0x0, -0x4ac(%rbp)
cmpl $0xa, -0x4ac(%rbp)
jae 0x40a4
leaq -0x4a8(%rbp), %rdi
leaq -0x494(%rbp), %rsi
addq $0x8, %rsi
movl -0x4ac(%rbp), %eax
imulq $0xc, %rax, %rax
addq %rax, %rsi
callq 0x3320
leaq -0x4a8(%rbp), %rdi
leaq -0x49e(%rbp), %rsi
callq 0x3480
cmpl $0x0, %eax
jne 0x4091
leaq -0x410(%rbp), %rdi
leaq 0x7ff3(%rip), %rsi      # 0xc078
callq 0x3320
movb $0x1, -0x411(%rbp)
jmp 0x4093
movl -0x4ac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4ac(%rbp)
jmp 0x4032
jmp 0x40a6
testb $0x1, -0x411(%rbp)
jne 0x40da
movq -0x10(%rbp), %rdi
callq 0x31b0
cmpq $0xa, %rax
jbe 0x40d8
leaq -0x410(%rbp), %rdi
leaq 0x7fbf(%rip), %rsi      # 0xc08b
callq 0x3320
movb $0x1, -0x411(%rbp)
jmp 0x40da
movq -0x540(%rbp), %rdi
callq 0x3a40
movw %ax, -0x4ae(%rbp)
movswl -0x4ae(%rbp), %eax
cmpl $0x0, %eax
jne 0x413f
movq -0x540(%rbp), %rdi
callq 0x3a40
movw %ax, -0x4ae(%rbp)
movswl -0x4ae(%rbp), %eax
cmpl $0x0, %eax
jne 0x413d
testb $0x1, -0x411(%rbp)
jne 0x413b
leaq -0x410(%rbp), %rdi
leaq 0x7f79(%rip), %rsi      # 0xc0a8
callq 0x3320
movb $0x1, -0x411(%rbp)
jmp 0x413d
jmp 0x413f
testb $0x1, -0x411(%rbp)
jne 0x416d
cmpl $0xa, -0x490(%rbp)
jne 0x416b
leaq -0x410(%rbp), %rdi
leaq 0x7f5d(%rip), %rsi      # 0xc0bc
callq 0x3320
movb $0x1, -0x411(%rbp)
jmp 0x416d
testb $0x1, -0x411(%rbp)
jne 0x429d
movl $0xffffffff, -0x530(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x52c(%rbp)
movl $0x0, -0x534(%rbp)
cmpl $0xa, -0x534(%rbp)
jge 0x41ed
leaq -0x530(%rbp), %rax
addq $0x8, %rax
movslq -0x534(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movw $0x0, 0xa(%rax)
leaq -0x530(%rbp), %rax
addq $0x8, %rax
movslq -0x534(%rbp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movb $0x0, (%rax)
movl -0x534(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x534(%rbp)
jmp 0x4198
movq -0x540(%rbp), %rdi
leaq -0x530(%rbp), %rdx
movswl -0x4ae(%rbp), %esi
callq 0x3c50
leaq -0x410(%rbp), %rdi
leaq 0x7ec0(%rip), %rsi      # 0xc0d5
callq 0x3320
leaq -0x410(%rbp), %rdi
leaq -0x49e(%rbp), %rsi
callq 0x3580
leaq -0x494(%rbp), %rdi
addq $0x8, %rdi
movl -0x490(%rbp), %eax
imulq $0xc, %rax, %rax
addq %rax, %rdi
leaq -0x49e(%rbp), %rsi
callq 0x3320
movq -0x540(%rbp), %rax
movw -0x4ae(%rbp), %dx
leaq -0x494(%rbp), %rcx
addq $0x8, %rcx
movl -0x490(%rbp), %esi
imulq $0xc, %rsi, %rsi
addq %rsi, %rcx
movw %dx, 0xa(%rcx)
movl -0x490(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x490(%rbp)
leaq -0x494(%rbp), %rdx
movq %rax, %rdi
movswl 0x4(%rax), %esi
callq 0x3c50
movq -0x540(%rbp), %rax
movl 0x8(%rax), %edi
leaq -0x410(%rbp), %rsi
movl $0x400, %edx            # imm = 0x400
xorl %ecx, %ecx
callq 0x31d0
addq $0x540, %rsp            # imm = 0x540
popq %rbp
retq
nopw %cs:(%rax,%rax)