#include <stdint.h>

#include "fs_private.h"

void FS_ClearDataForFiles(const void *rangeStart, const void *rangeEnd)
{
    const uintptr_t rangeStartAddress = (uintptr_t)rangeStart;
    const uintptr_t rangeEndAddress = (uintptr_t)rangeEnd;
    searchpath_t *search;
    fileInPack_t *packFile;
    fs_pack_file_clear_callback_t packCallback;
    fs_dir_file_list_t *dirList;
    fs_dir_file_t *dirFile;
    fs_dir_file_clear_callback_t dirCallback;
    int hashIndex;

    for (search = fs_lookup_searchpaths; search != NULL;
         search = FS_SearchpathNext(search)) {
        if (search->pack == NULL) {
            continue;
        }

        for (hashIndex = 0; hashIndex < search->pack->hashSize; hashIndex++) {
            for (packFile = search->pack->hashTable[hashIndex];
                 packFile != NULL; packFile = packFile->next) {
                const uintptr_t payloadAddress =
                    (uintptr_t)packFile->payload;
                if (rangeStartAddress <= payloadAddress &&
                    payloadAddress < rangeEndAddress) {
                    if (packFile->clearCallback != NULL) {
                        packCallback = packFile->clearCallback;
                        packCallback(&packFile->basename);
                        packFile->clearCallback = NULL;
                    }
                    packFile->payload = NULL;
                }
            }
        }
    }

    for (dirList = fs_lookup_dir_file_lists;
         dirList != NULL;
         dirList = FS_DirFileListNext(dirList)) {
        for (hashIndex = 0; hashIndex < dirList->hashSize; hashIndex++) {
            for (dirFile = dirList->hashTable[hashIndex];
                 dirFile != NULL; dirFile = dirFile->next) {
                const uintptr_t payloadAddress =
                    (uintptr_t)dirFile->payload;
                if (rangeStartAddress <= payloadAddress &&
                    payloadAddress < rangeEndAddress) {
                    if (dirFile->clearCallback != NULL) {
                        dirCallback = dirFile->clearCallback;
                        dirCallback(dirFile);
                        dirFile->clearCallback = NULL;
                    }
                    dirFile->payload = NULL;
                }
            }
        }
    }
}
