// Copyright 2020 Joe Drago. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause

#if !defined(_WIN32)
// Ensure off_t is 64 bits.
#undef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
// Ensure we have some POSIX compatibility with fseeko/ftello.
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#endif

#include "avif/internal.h"

#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#if defined(_WIN32)
// Windows uses _fseeki64 / _ftelli64 for large file support
typedef __int64 avif_off_t;
#define AVIF_OFF_MAX INT64_MAX

static int avif_fseeko(FILE * stream, avif_off_t offset, int whence)
{
    return _fseeki64(stream, offset, whence);
}

static avif_off_t avif_ftello(FILE * stream)
{
    return _ftelli64(stream);
}
#else

#include <unistd.h>

#if defined(__ANDROID__)
#include <android/api-level.h>
#if __ANDROID_API__ >= 24
#define AVIF_USE_FSEEKO
#endif
#elif defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
// Standard Modern POSIX. The _POSIX_VERSION >= 200112L test for fseeko/ftello
// is used in the first example in the APPLICATION USAGE section in
// https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/unistd.h.html.
#define AVIF_USE_FSEEKO
#endif

#if defined(AVIF_USE_FSEEKO)
// POSIX large file support
static_assert(sizeof(off_t) == sizeof(int64_t), "");
typedef off_t avif_off_t;
#define AVIF_OFF_MAX INT64_MAX

static int avif_fseeko(FILE * stream, avif_off_t offset, int whence)
{
    return fseeko(stream, offset, whence);
}

static avif_off_t avif_ftello(FILE * stream)
{
    return ftello(stream);
}
#else
// Unknown or very old platform. Fall back on fseek/ftell.
typedef long avif_off_t;
#define AVIF_OFF_MAX LONG_MAX

static int avif_fseeko(FILE * stream, avif_off_t offset, int whence)
{
    return fseek(stream, offset, whence);
}

static avif_off_t avif_ftello(FILE * stream)
{
    return ftell(stream);
}
#endif // defined(AVIF_USE_FSEEKO)

#endif // defined(_WIN32)

void avifIODestroy(avifIO * io)
{
    if (io && io->destroy) {
        io->destroy(io);
    }
}

// --------------------------------------------------------------------------------------
// avifIOMemoryReader

typedef struct avifIOMemoryReader
{
    avifIO io; // this must be the first member for easy casting to avifIO*
    avifROData rodata;
} avifIOMemoryReader;

static avifResult avifIOMemoryReaderRead(struct avifIO * io, uint32_t readFlags, uint64_t offset, size_t size, avifROData * out)
{
    // printf("avifIOMemoryReaderRead offset %" PRIu64 " size %zu\n", offset, size);

    if (readFlags != 0) {
        // Unsupported readFlags
        return AVIF_RESULT_IO_ERROR;
    }

    avifIOMemoryReader * reader = (avifIOMemoryReader *)io;

    // Sanitize/clamp incoming request
    if (offset > reader->rodata.size) {
        // The offset is past the end of the buffer.
        return AVIF_RESULT_IO_ERROR;
    }
    uint64_t availableSize = reader->rodata.size - offset;
    if (size > availableSize) {
        size = (size_t)availableSize;
    }

    // Prevent the offset addition from triggering an undefined behavior
    // sanitizer error if data is NULL (happens even with offset zero).
    out->data = offset ? reader->rodata.data + offset : reader->rodata.data;
    out->size = size;
    return AVIF_RESULT_OK;
}

static void avifIOMemoryReaderDestroy(struct avifIO * io)
{
    avifFree(io);
}

avifIO * avifIOCreateMemoryReader(const uint8_t * data, size_t size)
{
    avifIOMemoryReader * reader = (avifIOMemoryReader *)avifCalloc(1, sizeof(avifIOMemoryReader));
    if (reader == NULL) {
        return NULL;
    }
    reader->io.destroy = avifIOMemoryReaderDestroy;
    reader->io.read = avifIOMemoryReaderRead;
    reader->io.sizeHint = size;
    reader->io.persistent = AVIF_TRUE;
    reader->rodata.data = data;
    reader->rodata.size = size;
    return (avifIO *)reader;
}

// --------------------------------------------------------------------------------------
// avifIOFileReader

typedef struct avifIOFileReader
{
    avifIO io; // this must be the first member for easy casting to avifIO*
    avifRWData buffer;
    FILE * f;
} avifIOFileReader;

static avifResult avifIOFileReaderRead(struct avifIO * io, uint32_t readFlags, uint64_t offset, size_t size, avifROData * out)
{
    // printf("avifIOFileReaderRead offset %" PRIu64 " size %zu\n", offset, size);

    if (readFlags != 0) {
        // Unsupported readFlags
        return AVIF_RESULT_IO_ERROR;
    }

    avifIOFileReader * reader = (avifIOFileReader *)io;

    // Sanitize/clamp incoming request
    if (offset > reader->io.sizeHint) {
        // The offset is past the EOF.
        return AVIF_RESULT_IO_ERROR;
    }
    uint64_t availableSize = reader->io.sizeHint - offset;
    if (size > availableSize) {
        size = (size_t)availableSize;
    }

    if (size > 0) {
        if (offset > AVIF_OFF_MAX) {
            return AVIF_RESULT_IO_ERROR;
        }
        if (reader->buffer.size < size) {
            AVIF_CHECKRES(avifRWDataRealloc(&reader->buffer, size));
        }
        if (avif_fseeko(reader->f, (avif_off_t)offset, SEEK_SET) != 0) {
            return AVIF_RESULT_IO_ERROR;
        }
        size_t bytesRead = fread(reader->buffer.data, 1, size, reader->f);
        if (size != bytesRead) {
            if (ferror(reader->f)) {
                return AVIF_RESULT_IO_ERROR;
            }
            size = bytesRead;
        }
    }

    out->data = reader->buffer.data;
    out->size = size;
    return AVIF_RESULT_OK;
}

static void avifIOFileReaderDestroy(struct avifIO * io)
{
    avifIOFileReader * reader = (avifIOFileReader *)io;
    fclose(reader->f);
    avifRWDataFree(&reader->buffer);
    avifFree(io);
}

avifIO * avifIOCreateFileReader(const char * filename)
{
    FILE * f = fopen(filename, "rb");
    if (!f) {
        return NULL;
    }

    if (avif_fseeko(f, 0, SEEK_END) != 0) {
        fclose(f);
        return NULL;
    }
    avif_off_t fileSize = avif_ftello(f);
    if (fileSize < 0) {
        fclose(f);
        return NULL;
    }
    if (avif_fseeko(f, 0, SEEK_SET) != 0) {
        fclose(f);
        return NULL;
    }

    avifIOFileReader * reader = (avifIOFileReader *)avifCalloc(1, sizeof(avifIOFileReader));
    if (!reader) {
        fclose(f);
        return NULL;
    }
    reader->f = f;
    reader->io.destroy = avifIOFileReaderDestroy;
    reader->io.read = avifIOFileReaderRead;
    reader->io.sizeHint = (uint64_t)fileSize;
    reader->io.persistent = AVIF_FALSE;
    if (avifRWDataRealloc(&reader->buffer, 1024) != AVIF_RESULT_OK) {
        avifFree(reader);
        fclose(f);
        return NULL;
    }
    return (avifIO *)reader;
}
