#include "stdio.h"
#include "stdlib.h"
#include "FileUtilities.h"

static char _filenameAndExtensionBuffer[MAX_PATH + 1];

static char _driveBuffer[MAX_PATH + 1];
static char _directoryBuffer[MAX_PATH + 1];
static char _filenameBuffer[MAX_PATH + 1];
static char _extensionBuffer[MAX_PATH + 1];

WCHAR** file_utilities__list_files_in_directory(WCHAR* directory, WCHAR* fileMask, int* numFilesOUT)
{
    WIN32_FIND_DATA findFileData;
    HANDLE hFind = NULL;

    *numFilesOUT = 0;

#define MAX_FULL_PATH 2048
    WCHAR* fullPath = (WCHAR*)malloc((MAX_FULL_PATH + 1) * sizeof(WCHAR));
    if (fullPath == NULL) {
        return NULL;
    }

    // file mask
    swprintf(fullPath, MAX_FULL_PATH, L"%s\\%s", directory, fileMask);

    if ((hFind = FindFirstFileW(fullPath, &findFileData)) == INVALID_HANDLE_VALUE)
    {
        // directory is inaccessible, so we're done
        free(fullPath);
        return NULL;
    }

#define MAX_RESULTS 1024
    WCHAR** result = (WCHAR**)malloc(MAX_RESULTS * sizeof(WCHAR*));
    if (result == NULL) {
        free(fullPath);
        return NULL;
    }

    do
    {
        // exclude directories
        if (!wcscmp(findFileData.cFileName, L".") || !wcscmp(findFileData.cFileName, L".."))
        {
            continue;
        }

        // build full path from passed-in directory and file name
        swprintf(fullPath, MAX_FULL_PATH, L"%s\\%s", directory, findFileData.cFileName);

        if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
        {
            // it's a file (as opposed to a directory)

            // store it in the result
            result[*numFilesOUT] = (WCHAR*)malloc((MAX_FULL_PATH + 1) * sizeof(WCHAR));
            if (result[*numFilesOUT] == NULL) {
                // as soon as we fail one allocation, we're done
                break;
            }

            // copy full path into result
            swprintf(result[*numFilesOUT], MAX_FULL_PATH, L"%s", fullPath);

            // we've successfully accumulated the file
            (*numFilesOUT)++;
        }
    } while (FindNextFile(hFind, &findFileData) && ((*numFilesOUT) < MAX_RESULTS));

    FindClose(hFind);
    free(fullPath);
    return result;
}

const char* file_utilities__get_file_name_and_extension(const char* absolutePath)
{
    errno_t result = _splitpath_s(
        absolutePath,
        _driveBuffer,
        MAX_PATH + 1,
        _directoryBuffer,
        MAX_PATH + 1,
        _filenameBuffer,
        MAX_PATH + 1,
        _extensionBuffer,
        MAX_PATH + 1);
    if (result) {
        return NULL;
    }

    sprintf_s(_filenameAndExtensionBuffer, MAX_PATH+1, "%s%s", _filenameBuffer, _extensionBuffer);
    return _filenameAndExtensionBuffer;
}
