// File: /workspace/github_c_makefile_star2_O2/justy989[P]ce/ce_commands.c
// Function: command_discover_directory_files
CeCommandStatus_t command_discover_directory_files(CeCommand_t* command, void* user_data){
    CeApp_t* app = user_data;
    CommandContext_t command_context = {};

    if(!get_command_context(app, &command_context)) return CE_COMMAND_NO_ACTION;

    if(command->arg_count <= 0 ||
       command->args[0].type != CE_COMMAND_ARG_STRING){
        return CE_COMMAND_PRINT_HELP;
    }

    char base_directory[MAX_PATH_LEN];
#if defined(PLATFORM_WINDOWS)
    snprintf(base_directory, MAX_PATH_LEN, "%s\\*", command->args[0].string);
#else
    snprintf(base_directory, MAX_PATH_LEN, "%s", command->args[0].string);
#endif

    // setup our ignore dirs
    int ignore_dir_count = (command->arg_count - 1);
    char** ignore_dirs = malloc(sizeof(*ignore_dirs) * ignore_dir_count);
    for(int64_t i = 1; i < command->arg_count; i++){
        // TODO: this imposes a restriction that folders cannot be named numbers like 5
        if(command->args[i].type != CE_COMMAND_ARG_STRING){
            return CE_COMMAND_PRINT_HELP;
        }
        ignore_dirs[i - 1] = strdup(command->args[i].string);
    }

    int* ignore_dir_lens = malloc(sizeof(*ignore_dir_lens) * ignore_dir_count);
    for(int64_t i = 0; i < ignore_dir_count; i++){
        ignore_dir_lens[i] = strlen(ignore_dirs[i]);
    }

    // head is a dummy node that doesn't contain any info, just makes the find_files_in_directory_recursively()
    // interface better
    CeStrNode_t* head = calloc(sizeof(*head), 1);
    find_files_in_directory_recursively(base_directory, head, ignore_dirs, ignore_dir_lens, ignore_dir_count);

    // cleanup our ignore dirs
    for(int64_t i = 0; i < ignore_dir_count; i++){
        free(ignore_dirs[i]);
    }
    free(ignore_dirs);
    free(ignore_dir_lens);

    // Count the paths.
    int64_t filepath_count = 0;
    CeStrNode_t* itr = head;
    while(itr){
        if(itr->string){
            filepath_count++;
        }
        itr = itr->next;
    }

    // Build an array of strings for the paths.
    char** filepaths = malloc(filepath_count * sizeof(filepaths[0]));
    bool* filepaths_already_exists = calloc(filepath_count, sizeof(filepaths_already_exists[0]));

    int64_t filepath_index = 0;
    itr = head;
    while(itr){
        if(itr->string){
            filepaths[filepath_index] = strdup(itr->string);
            filepath_index++;
        }
        CeStrNode_t* node = itr;
        itr = itr->next;
        free(node->string);
        free(node);
    }

    // Sort the filepaths.
    qsort(filepaths,
          filepath_count,
          sizeof(filepaths[0]),
          _strstrcmp);

    // Since both lists are sorted, compare the elements in lock step.
    int64_t matching_filepath_count = 0;
    int64_t discovered_index = 0;
    filepath_index = 0;
    while(filepath_index < filepath_count &&
          discovered_index < app->discovered_filepath_count){
        int rc = strcmp(filepaths[filepath_index],
                        app->discovered_filepaths[discovered_index]);
        if(rc < 0){
            discovered_index++;
        }else if(rc > 0){
            filepath_index++;
        }else{
            filepaths_already_exists[filepath_index] = true;
            matching_filepath_count++;
            filepath_index++;
            discovered_index++;
        }
    }

    int64_t new_filepath_count = filepath_count - matching_filepath_count;
    if(new_filepath_count > 0){
        int64_t new_discovered_filepath_count = app->discovered_filepath_count + new_filepath_count;
        app->discovered_filepaths = realloc(
            app->discovered_filepaths,
            sizeof(*app->discovered_filepaths) * new_discovered_filepath_count);

        discovered_index = app->discovered_filepath_count;
        for(int64_t i = 0; i < filepath_count; i++){
            if(!filepaths_already_exists[i]){
                app->discovered_filepaths[discovered_index] = strdup(filepaths[i]);
                discovered_index++;
            }
        }

        app->discovered_filepath_count = new_discovered_filepath_count;

        // Sort the final list of paths.
        qsort(app->discovered_filepaths,
              app->discovered_filepath_count,
              sizeof(app->discovered_filepaths[0]),
              _strstrcmp);
    }

    for(int64_t i = 0; i < filepath_count; i++){
        free(filepaths[i]);
    }
    free(filepaths);
    free(filepaths_already_exists);

    // setup input and completion
    ce_app_input(app, "Load Discovered File", load_project_file_input_complete_func);
    ce_complete_init(&app->input_complete, (const char**)(app->discovered_filepaths), NULL, app->discovered_filepath_count);
    build_complete_list(app->complete_list_buffer, &app->input_complete);

    return CE_COMMAND_SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x438, %rsp            # imm = 0x438
movq %rsi, %rbx
movq %rdi, %r12
leaq 0x20(%rsp), %rsi
movq %rbx, %rdi
callq 0x15be9
testb %al, %al
je 0x16a4e
pushq $0x2
popq %r13
cmpq $0x0, 0x208(%r12)
jle 0x16a52
movq 0x200(%r12), %rax
cmpl $0x2, (%rax)
jne 0x16a52
movq %rbx, 0x18(%rsp)
movq 0x8(%rax), %rcx
leaq 0x16f38(%rip), %rdx     # 0x2d906
xorl %r15d, %r15d
leaq 0x30(%rsp), %rdi
movl $0x400, %esi            # imm = 0x400
xorl %eax, %eax
callq 0xd260
movq 0x208(%r12), %rbx
movq %rbx, %rax
shlq $0x20, %rax
movabsq $-0x100000000, %rdi     # imm = 0xFFFFFFFF00000000
addq %rax, %rdi
movq %rdi, %rax
sarq $0x20, %rax
movq %rax, 0x8(%rsp)
movq %rdi, 0x10(%rsp)
sarq $0x1d, %rdi
callq 0xd4c0
movq %rax, %r14
pushq $0x1
popq %rbp
pushq $0x2
popq %r13
cmpq %rbx, %rbp
jge 0x16a67
movq 0x200(%r12), %rax
cmpl $0x2, 0x10(%rax,%r15,2)
jne 0x16a52
movq 0x18(%rax,%r15,2), %rdi
callq 0xd640
movq %rax, (%r14,%r15)
incq %rbp
addq $0x8, %r15
jmp 0x16a22
pushq $0x3
popq %r13
movl %r13d, %eax
addq $0x438, %rsp            # imm = 0x438
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x10(%rsp), %rdi
sarq $0x1e, %rdi
callq 0xd4c0
movq %rax, %r12
xorl %ebx, %ebx
movq 0x8(%rsp), %r13
testq %r13, %r13
movl $0x0, %ebp
cmovgq %r13, %rbp
cmpq %rbx, %rbp
je 0x16aa2
movq (%r14,%rbx,8), %rdi
callq 0xd210
movl %eax, (%r12,%rbx,4)
incq %rbx
jmp 0x16a8b
pushq $0x10
popq %rdi
pushq $0x1
popq %rsi
callq 0xd380
movq %rax, %r15
leaq 0x30(%rsp), %rdi
movq %rax, %rsi
movq %r14, %rdx
movq %r12, %rcx
movq %r13, %r8
callq 0x1676d
xorl %ebx, %ebx
cmpq %rbx, %rbp
je 0x16adb
movq (%r14,%rbx,8), %rdi
callq 0xd090
incq %rbx
jmp 0x16ac8
movq %r14, %rdi
callq 0xd090
movq %r12, %rdi
callq 0xd090
xorl %r14d, %r14d
movq %r15, %rax
testq %rax, %rax
je 0x16b04
cmpq $0x1, (%rax)
movq 0x8(%rax), %rax
sbbq $-0x1, %r14
jmp 0x16af1
leaq (,%r14,8), %rdi
callq 0xd4c0
movq %rax, %r12
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0xd380
movq %rax, 0x8(%rsp)
xorl %ebx, %ebx
testq %r15, %r15
je 0x16b5b
movq (%r15), %rbp
testq %rbp, %rbp
je 0x16b42
movq %rbp, %rdi
callq 0xd640
movq %rax, (%r12,%rbx,8)
incq %rbx
movq 0x8(%r15), %r13
movq %rbp, %rdi
callq 0xd090
movq %r15, %rdi
callq 0xd090
movq %r13, %r15
jmp 0x16b26
leaq -0x1ff(%rip), %rcx      # 0x16963
pushq $0x8
popq %rdx
movq %r12, %rdi
movq %r14, %rsi
callq 0xd140
xorl %r13d, %r13d
xorl %ebx, %ebx
xorl %ebp, %ebp
movq 0x18(%rsp), %r15
cmpq %r14, %r13
jge 0x16bc0
cmpq 0x2cb0(%r15), %rbp
jge 0x16bc0
movq (%r12,%r13,8), %rdi
movq 0x2cb8(%r15), %rax
movq (%rax,%rbp,8), %rsi
callq 0xd390
testl %eax, %eax
jns 0x16ba7
incq %rbp
jmp 0x16b7c
je 0x16bae
incq %r13
jmp 0x16b7c
movq 0x8(%rsp), %rax
movb $0x1, (%rax,%r13)
incq %rbx
incq %r13
jmp 0x16ba2
movq %r14, %r13
subq %rbx, %r13
jle 0x16c3f
addq 0x2cb0(%r15), %r13
movq 0x2cb8(%r15), %rdi
leaq (,%r13,8), %rsi
callq 0xd520
movq %rax, 0x2cb8(%r15)
movq 0x2cb0(%r15), %rbx
xorl %ebp, %ebp
cmpq %rbp, %r14
je 0x16c1f
movq 0x8(%rsp), %rax
cmpb $0x0, (%rax,%rbp)
jne 0x16c1a
movq (%r12,%rbp,8), %rdi
callq 0xd640
movq 0x2cb8(%r15), %rcx
movq %rax, (%rcx,%rbx,8)
incq %rbx
incq %rbp
jmp 0x16bf3
movq %r13, 0x2cb0(%r15)
movq 0x2cb8(%r15), %rdi
leaq -0x2d1(%rip), %rcx      # 0x16963
pushq $0x8
popq %rdx
movq %r13, %rsi
callq 0xd140
xorl %ebx, %ebx
cmpq %rbx, %r14
je 0x16c54
movq (%r12,%rbx,8), %rdi
callq 0xd090
incq %rbx
jmp 0x16c41
movq %r12, %rdi
callq 0xd090
movq 0x8(%rsp), %rdi
callq 0xd090
leaq 0x15716(%rip), %rsi     # 0x2c383
leaq -0x34a1(%rip), %rdx     # 0x137d3
movq %r15, %rdi
callq 0x11d3f
leaq 0x28a0(%r15), %r14
movq 0x2cb0(%r15), %rcx
movq 0x2cb8(%r15), %rsi
xorl %r13d, %r13d
movq %r14, %rdi
xorl %edx, %edx
callq 0x18d58
movq 0x2860(%r15), %rdi
movq %r14, %rsi
callq 0x11518
jmp 0x16a52