// File: /workspace/github_c_makefile_star2_O3/justy989[P]ce/ce_clangd.c
// Function: ce_clangd_init
bool ce_clangd_init(const char* executable_path,
                    CeClangD_t* clangd){
     char command[MAX_COMMAND_SIZE];
     // DEBUG
     // snprintf(command, MAX_COMMAND_SIZE, "%s --log=verbose", executable_path);
     snprintf(command, MAX_COMMAND_SIZE, "%s", executable_path);
     bool use_shell = false;
     if(!ce_subprocess_open(&clangd->proc, command, CE_PROC_COMM_STDIN | CE_PROC_COMM_STDOUT, use_shell)){
          return false;
     }

     HandleOutputData_t* thread_data = malloc(sizeof(*thread_data));
     thread_data->buffer = clangd->buffer;
     thread_data->proc = &clangd->proc;
     thread_data->response_queue = &clangd->response_queue;

#if defined(PLATFORM_WINDOWS)
     clangd->response_queue.mutex = CreateMutex(NULL, false, NULL);
     if(clangd->response_queue.mutex == NULL){
          ce_log("Failed to create clangd mutex\n");
          return false;
     }

     clangd->thread_handle = CreateThread(NULL,
                                          0,
                                          handle_output_fn,
                                          thread_data,
                                          0,
                                          &clangd->thread_id);
     if(clangd->thread_handle == INVALID_HANDLE_VALUE){
          ce_log("failed to create thread to run command\n");
          return false;
     }
#else
     int rc = pthread_create(&clangd->thread, NULL, handle_output_fn, thread_data);
     if(rc != 0){
          ce_log("pthread_create() failed: '%s'\n", strerror(errno));
          return false;
     }

     rc = pthread_mutex_init(&clangd->response_queue.mutex, NULL);
     if(rc != 0){
          ce_log("pthread_mutex_init() failed: %s\n", strerror(rc));
          return false;
     }
#endif

     // Build our initialization structure.
     CeJsonObj_t initialize_obj = {};
     ce_json_obj_set_string(&initialize_obj, "jsonrpc", "2.0");
     ce_json_obj_set_number(&initialize_obj, "id", 0);
     ce_json_obj_set_string(&initialize_obj, "method", "initialize");

     char cwd[MAX_PATH_LEN + 1];
     char cwd_uri[MAX_PATH_LEN + 16];

     CeJsonObj_t params_obj = {};

#if defined(PLATFORM_WINDOWS)
     DWORD pid = GetCurrentProcessId();
     _getcwd(cwd, MAX_PATH_LEN);
#else
     pid_t pid = getpid();
     getcwd(cwd, MAX_PATH_LEN);
#endif
     ce_json_obj_set_number(&params_obj, "processId", (double)(pid));

#if defined(PLATFORM_WINDOWS)
     strncpy(cwd_uri, cwd, MAX_PATH_LEN);
     _convert_windows_path_to_uri(cwd_uri, MAX_PATH_LEN);
     char* json_cwd = _convert_string_to_json_string(cwd);
#else
     snprintf(cwd_uri, MAX_PATH_LEN + 15, "file://%s", cwd);
     char* json_cwd = _convert_string_to_json_string(cwd);
#endif

     ce_json_obj_set_string(&params_obj, "rootPath", json_cwd);
     ce_json_obj_set_string(&params_obj, "rootUri", cwd_uri);
     ce_json_obj_set_obj(&initialize_obj, "params", &params_obj);

     CeJsonObj_t client_info_obj = {};
     ce_json_obj_set_string(&client_info_obj, "name", "ce");
     ce_json_obj_set_string(&client_info_obj, "version", "9.8.7");
     ce_json_obj_set_obj(&initialize_obj, "ClientInfo", &client_info_obj);

     bool result = _send_json_obj(&initialize_obj, &clangd->proc);
     ce_json_obj_free(&initialize_obj);
     ce_json_obj_free(&params_obj);
     ce_json_obj_free(&client_info_obj);

     free(json_cwd);
     return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc58, %rsp            # imm = 0xC58
movq %rsi, %r14
movq %rdi, %rcx
leaq 0x1bbf0(%rip), %rdx     # 0x30966
xorl %ebp, %ebp
leaq 0x30(%rsp), %r15
movl $0x400, %esi            # imm = 0x400
movq %r15, %rdi
xorl %eax, %eax
callq 0xd260
leaq 0x8(%r14), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movl $0x3, %edx
xorl %ecx, %ecx
callq 0x1f552
testb %al, %al
je 0x14e1c
movl $0x18, %edi
callq 0xd4c0
movq 0x28(%r14), %rcx
movq %rcx, (%rax)
movq %rbx, 0x8(%rax)
leaq 0x38(%r14), %rcx
movq %rcx, 0x10(%rax)
leaq 0x1cd(%rip), %rdx       # 0x14f97
movq %r14, %rdi
xorl %esi, %esi
movq %rax, %rcx
callq 0xd570
testl %eax, %eax
je 0x14df0
callq 0xd0a0
movl (%rax), %edi
callq 0xd650
leaq 0x19f6e(%rip), %rdi     # 0x2ed5c
jmp 0x14e10
addq $0x48, %r14
movq %r14, %rdi
xorl %esi, %esi
callq 0xd6c0
testl %eax, %eax
je 0x14e30
movl %eax, %edi
callq 0xd650
leaq 0x1a218(%rip), %rdi     # 0x2f028
xorl %ebp, %ebp
movq %rax, %rsi
xorl %eax, %eax
callq 0xd954
movl %ebp, %eax
addq $0xc58, %rsp            # imm = 0xC58
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %r14
movaps %xmm0, (%r14)
leaq 0x1a206(%rip), %rsi     # 0x2f049
leaq 0x1a207(%rip), %rdx     # 0x2f051
movq %r14, %rdi
callq 0x1c4b8
leaq 0x1b277(%rip), %rsi     # 0x300d0
xorps %xmm0, %xmm0
movq %r14, %rdi
callq 0x1c53b
leaq 0x19e55(%rip), %rsi     # 0x2ecc0
leaq 0x1a1e3(%rip), %rdx     # 0x2f055
movq %r14, %rdi
callq 0x1c4b8
leaq 0x10(%rsp), %r15
xorps %xmm0, %xmm0
movaps %xmm0, (%r15)
callq 0xd1e0
movl %eax, %ebp
leaq 0x430(%rsp), %r12
movl $0x400, %esi            # imm = 0x400
movq %r12, %rdi
callq 0xd2d0
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
leaq 0x1a1b0(%rip), %rsi     # 0x2f060
movq %r15, %rdi
callq 0x1c53b
leaq 0x1a1ab(%rip), %rdx     # 0x2f06a
leaq 0x840(%rsp), %r13
movl $0x40f, %esi            # imm = 0x40F
movq %r13, %rdi
movq %r12, %rcx
xorl %eax, %eax
callq 0xd260
movq %r12, %rdi
callq 0x154a4
movq %rax, %r12
leaq 0x1a189(%rip), %rsi     # 0x2f074
movq %r15, %rdi
movq %rax, %rdx
callq 0x1c4b8
leaq 0x1a180(%rip), %rsi     # 0x2f07d
movq %r15, %rdi
movq %r13, %rdx
callq 0x1c4b8
leaq 0x19ced(%rip), %rsi     # 0x2ebfc
movq %r14, %rdi
movq %r15, %rdx
callq 0x1c1a3
movq %rsp, %r13
xorpd %xmm0, %xmm0
movapd %xmm0, (%r13)
leaq 0x19759(%rip), %rsi     # 0x2e687
leaq 0x18227(%rip), %rdx     # 0x2d15c
movq %r13, %rdi
callq 0x1c4b8
leaq 0x1a141(%rip), %rsi     # 0x2f085
leaq 0x1a142(%rip), %rdx     # 0x2f08d
movq %r13, %rdi
callq 0x1c4b8
leaq 0x1a139(%rip), %rsi     # 0x2f093
movq %r14, %rdi
movq %r13, %rdx
callq 0x1c1a3
movq %r14, %rdi
movq %rbx, %rsi
callq 0x155b2
movl %eax, %ebp
movq %r14, %rdi
callq 0x1c6aa
movq %r15, %rdi
callq 0x1c6aa
movq %r13, %rdi
callq 0x1c6aa
movq %r12, %rdi
callq 0xd090
jmp 0x14e1c