// File: /workspace/github_c_makefile_star2_O0/deplinenoise[P]tundra/src/FileInfo.cpp
// Function: t2::ListDirectory(char const*, void*, void (*)(void*, t2::FileInfo const&, char const*))
void ListDirectory(
    const char* path,
    void* user_data,
    void (*callback)(void* user_data, const FileInfo& info, const char* path))
{
#if defined(TUNDRA_UNIX)
	char full_fn[512];
	struct dirent entry;
	struct dirent* result = NULL;
	const size_t path_len = strlen(path);

	if (path_len + 1 > sizeof(full_fn)) {
    Log(kWarning, "path too long: %s", path);
		return;
  }

	strcpy(full_fn, path);

	DIR* dir = opendir(path);

	if (!dir)
  {
    Log(kWarning, "opendir() failed: %s", path);
		return;
  }

	while (0 == readdir_r(dir, &entry, &result) && result)
	{
    size_t len = strlen(entry.d_name);

    if (ShouldFilter(entry.d_name, len))
      continue;

		if (len + path_len + 2 >= sizeof(full_fn))
    {
			Log(kWarning, "%s: name too long\n", entry.d_name);
      continue;
    }

		full_fn[path_len] = '/';
		strcpy(full_fn + path_len + 1, entry.d_name);

    FileInfo info = GetFileInfo(full_fn);
    (*callback)(user_data, info, entry.d_name);
	}

	closedir(dir);

#else
	WIN32_FIND_DATAA find_data;
	char             scan_path[MAX_PATH];

	_snprintf(scan_path, sizeof(scan_path), "%s/*", path);

	for (int i = 0; i < MAX_PATH; ++i)
	{
		char ch = scan_path[i];
		if ('/' == ch)
			scan_path[i] = '\\';
		else if ('\0' == ch)
			break;
	}

	HANDLE h = FindFirstFileA(scan_path, &find_data);

	if (INVALID_HANDLE_VALUE == h)
  {
    Log(kWarning, "FindFirstFile() failed: %s", path);
		return;
  }

	do
	{
    if (ShouldFilter(find_data.cFileName, strlen(find_data.cFileName)))
      continue;

    static const uint64_t kEpochDiff = 0x019DB1DED53E8000LL; // 116444736000000000 nsecs
    static const uint64_t kRateDiff = 10000000; // 100 nsecs

    uint64_t ft = uint64_t(find_data.ftLastWriteTime.dwHighDateTime) << 32 | find_data.ftLastWriteTime.dwLowDateTime;

    FileInfo info;
    info.m_Flags     = FileInfo::kFlagExists;
    info.m_Size      = uint64_t(find_data.nFileSizeHigh) << 32 | find_data.nFileSizeLow;
    info.m_Timestamp = (ft - kEpochDiff) / kRateDiff;

    if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes)
      info.m_Flags |= FileInfo::kFlagDirectory;
    else
      info.m_Flags |= FileInfo::kFlagFile;

    (*callback)(user_data, info, find_data.cFileName);

	} while (FindNextFileA(h, &find_data));

	if (!FindClose(h))
		CroakErrno("couldn't close FindFile handle");
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x380, %rsp            # imm = 0x380
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq $0x0, -0x340(%rbp)
movq -0x8(%rbp), %rdi
callq 0x3150
movq %rax, -0x348(%rbp)
movq -0x348(%rbp), %rax
addq $0x1, %rax
cmpq $0x200, %rax            # imm = 0x200
jbe 0x16bd1
movq -0x8(%rbp), %rdx
movl $0x2, %edi
leaq 0xded2(%rip), %rsi      # 0x24a97
movb $0x0, %al
callq 0x7a60
jmp 0x16d47
leaq -0x220(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x3330
movq -0x8(%rbp), %rdi
callq 0x34f0
movq %rax, -0x350(%rbp)
cmpq $0x0, -0x350(%rbp)
jne 0x16c17
movq -0x8(%rbp), %rdx
movl $0x2, %edi
leaq 0xde9e(%rip), %rsi      # 0x24aa9
movb $0x0, %al
callq 0x7a60
jmp 0x16d47
jmp 0x16c19
movq -0x350(%rbp), %rdi
leaq -0x338(%rbp), %rsi
leaq -0x340(%rbp), %rdx
callq 0x3100
movl %eax, %edx
xorl %eax, %eax
xorl %ecx, %ecx
cmpl %edx, %ecx
movb %al, -0x371(%rbp)
jne 0x16c54
cmpq $0x0, -0x340(%rbp)
setne %al
movb %al, -0x371(%rbp)
movb -0x371(%rbp), %al
testb $0x1, %al
jne 0x16c63
jmp 0x16d3b
leaq -0x338(%rbp), %rdi
addq $0x13, %rdi
callq 0x3150
movq %rax, -0x358(%rbp)
leaq -0x338(%rbp), %rdi
addq $0x13, %rdi
movq -0x358(%rbp), %rsi
callq 0x16a70
testb $0x1, %al
jne 0x16c97
jmp 0x16c99
jmp 0x16c19
movq -0x358(%rbp), %rax
addq -0x348(%rbp), %rax
addq $0x2, %rax
cmpq $0x200, %rax            # imm = 0x200
jb 0x16cd6
leaq -0x338(%rbp), %rdx
addq $0x13, %rdx
movl $0x2, %edi
leaq 0xddf4(%rip), %rsi      # 0x24abe
movb $0x0, %al
callq 0x7a60
jmp 0x16c19
movq -0x348(%rbp), %rax
movb $0x2f, -0x220(%rbp,%rax)
leaq -0x220(%rbp), %rdi
addq -0x348(%rbp), %rdi
addq $0x1, %rdi
leaq -0x338(%rbp), %rsi
addq $0x13, %rsi
callq 0x3330
leaq -0x220(%rbp), %rsi
leaq -0x370(%rbp), %rdi
callq 0x16920
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rdi
leaq -0x338(%rbp), %rdx
addq $0x13, %rdx
leaq -0x370(%rbp), %rsi
callq *%rax
jmp 0x16c19
movq -0x350(%rbp), %rdi
callq 0x3560
addq $0x380, %rsp            # imm = 0x380
popq %rbp
retq