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

#include "avif/internal.h"

#include <assert.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>

// ---------------------------------------------------------------------------
// avifROStream

const uint8_t * avifROStreamCurrent(avifROStream * stream)
{
    return stream->raw->data + stream->offset;
}

void avifROStreamStart(avifROStream * stream, avifROData * raw, avifDiagnostics * diag, const char * diagContext)
{
    stream->raw = raw;
    stream->offset = 0;
    stream->numUsedBitsInPartialByte = 0;
    stream->diag = diag;
    stream->diagContext = diagContext;

    // If diag is non-NULL, diagContext must also be non-NULL
    assert(!stream->diag || stream->diagContext);
}

avifBool avifROStreamHasBytesLeft(const avifROStream * stream, size_t byteCount)
{
    return byteCount <= (stream->raw->size - stream->offset);
}

size_t avifROStreamRemainingBytes(const avifROStream * stream)
{
    return stream->raw->size - stream->offset;
}

size_t avifROStreamOffset(const avifROStream * stream)
{
    return stream->offset;
}

void avifROStreamSetOffset(avifROStream * stream, size_t offset)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    stream->offset = offset;
    if (stream->offset > stream->raw->size) {
        stream->offset = stream->raw->size;
    }
}

avifBool avifROStreamSkip(avifROStream * stream, size_t byteCount)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    if (!avifROStreamHasBytesLeft(stream, byteCount)) {
        avifDiagnosticsPrintf(stream->diag, "%s: Failed to skip %zu bytes, truncated data?", stream->diagContext, byteCount);
        return AVIF_FALSE;
    }
    stream->offset += byteCount;
    return AVIF_TRUE;
}

avifBool avifROStreamRead(avifROStream * stream, uint8_t * data, size_t size)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    if (!avifROStreamHasBytesLeft(stream, size)) {
        avifDiagnosticsPrintf(stream->diag, "%s: Failed to read %zu bytes, truncated data?", stream->diagContext, size);
        return AVIF_FALSE;
    }

    memcpy(data, stream->raw->data + stream->offset, size);
    stream->offset += size;
    return AVIF_TRUE;
}

avifBool avifROStreamReadUX8(avifROStream * stream, uint64_t * v, uint64_t factor)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    if (factor == 0) {
        // Don't read anything, just set to 0
        *v = 0;
    } else if (factor == 1) {
        uint8_t tmp;
        AVIF_CHECK(avifROStreamRead(stream, &tmp, 1));
        *v = tmp;
    } else if (factor == 2) {
        uint16_t tmp;
        AVIF_CHECK(avifROStreamReadU16(stream, &tmp));
        *v = tmp;
    } else if (factor == 4) {
        uint32_t tmp;
        AVIF_CHECK(avifROStreamReadU32(stream, &tmp));
        *v = tmp;
    } else if (factor == 8) {
        uint64_t tmp;
        AVIF_CHECK(avifROStreamReadU64(stream, &tmp));
        *v = tmp;
    } else {
        // Unsupported factor
        avifDiagnosticsPrintf(stream->diag, "%s: Failed to read UX8 value; Unsupported UX8 factor [%" PRIu64 "]", stream->diagContext, factor);
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

avifBool avifROStreamReadU16(avifROStream * stream, uint16_t * v)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    AVIF_CHECK(avifROStreamRead(stream, (uint8_t *)v, sizeof(uint16_t)));
    *v = avifNTOHS(*v);
    return AVIF_TRUE;
}

avifBool avifROStreamReadU16Endianness(avifROStream * stream, uint16_t * v, avifBool littleEndian)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    AVIF_CHECK(avifROStreamRead(stream, (uint8_t *)v, sizeof(uint16_t)));
    *v = littleEndian ? avifCTOHS(*v) : avifNTOHS(*v);
    return AVIF_TRUE;
}

avifBool avifROStreamReadU32(avifROStream * stream, uint32_t * v)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    AVIF_CHECK(avifROStreamRead(stream, (uint8_t *)v, sizeof(uint32_t)));
    *v = avifNTOHL(*v);
    return AVIF_TRUE;
}

avifBool avifROStreamReadU32Endianness(avifROStream * stream, uint32_t * v, avifBool littleEndian)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    AVIF_CHECK(avifROStreamRead(stream, (uint8_t *)v, sizeof(uint32_t)));
    *v = littleEndian ? avifCTOHL(*v) : avifNTOHL(*v);
    return AVIF_TRUE;
}

avifBool avifROStreamReadU64(avifROStream * stream, uint64_t * v)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    AVIF_CHECK(avifROStreamRead(stream, (uint8_t *)v, sizeof(uint64_t)));
    *v = avifNTOH64(*v);
    return AVIF_TRUE;
}

// Override of avifROStreamReadBits() for convenient uint8_t output.
avifBool avifROStreamReadBits8(avifROStream * stream, uint8_t * v, size_t bitCount)
{
    assert(bitCount <= sizeof(*v) * 8);
    uint32_t v32;
    if (!avifROStreamReadBits(stream, &v32, bitCount)) {
        return AVIF_FALSE;
    }
    *v = (uint8_t)v32;
    return AVIF_TRUE;
}

avifBool avifROStreamReadBits(avifROStream * stream, uint32_t * v, size_t bitCount)
{
    assert(bitCount <= sizeof(*v) * 8);
    *v = 0;
    while (bitCount) {
        if (stream->numUsedBitsInPartialByte == 0) {
            AVIF_CHECK(avifROStreamSkip(stream, sizeof(uint8_t))); // Book a new partial byte in the stream.
        }
        assert(stream->offset > 0);
        const uint8_t * packedBits = stream->raw->data + stream->offset - 1;

        const size_t numBits = AVIF_MIN(bitCount, 8 - stream->numUsedBitsInPartialByte);
        stream->numUsedBitsInPartialByte += numBits;
        bitCount -= numBits;
        // The stream bits are packed starting with the most significant bit of the first input byte.
        // This way, packed bits can be found in the same order in the bit stream.
        const uint32_t bits = (*packedBits >> (8 - stream->numUsedBitsInPartialByte)) & ((1 << numBits) - 1);
        // The value bits are ordered from the most significant bit to the least significant bit.
        // In the case where avifROStreamReadBits() is used to parse the unsigned integer value *v
        // over multiple aligned bytes, this order corresponds to big endianness.
        *v |= bits << bitCount;

        if (stream->numUsedBitsInPartialByte == 8) {
            // Start a new partial byte the next time a bit is needed.
            stream->numUsedBitsInPartialByte = 0;
        }
    }
    return AVIF_TRUE;
}

static const int VARINT_DEPTH_0 = 7; // +1 bit to stop or continue.
static const int VARINT_DEPTH_1 = 3; // +1 bit to stop or continue.
static const int VARINT_DEPTH_2 = 18;

avifBool avifROStreamReadVarInt(avifROStream * stream, uint32_t * v)
{
    AVIF_CHECK(avifROStreamReadBits(stream, v, VARINT_DEPTH_0));
    uint32_t extended, extension;

    AVIF_CHECK(avifROStreamReadBits(stream, &extended, 1));
    if (extended) {
        AVIF_CHECK(avifROStreamReadBits(stream, &extension, VARINT_DEPTH_1));
        *v += (extension + 1) << VARINT_DEPTH_0;

        AVIF_CHECK(avifROStreamReadBits(stream, &extended, 1));
        if (extended) {
            AVIF_CHECK(avifROStreamReadBits(stream, &extension, VARINT_DEPTH_2));
            *v += (extension + 1) << (VARINT_DEPTH_0 + VARINT_DEPTH_1);
        }
    }
    return AVIF_TRUE;
}

avifBool avifROStreamReadString(avifROStream * stream, char * output, size_t outputSize)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.

    // Check for the presence of a null terminator in the stream.
    size_t remainingBytes = avifROStreamRemainingBytes(stream);
    const uint8_t * p = avifROStreamCurrent(stream);
    avifBool foundNullTerminator = AVIF_FALSE;
    for (size_t i = 0; i < remainingBytes; ++i) {
        if (p[i] == 0) {
            foundNullTerminator = AVIF_TRUE;
            break;
        }
    }
    if (!foundNullTerminator) {
        avifDiagnosticsPrintf(stream->diag, "%s: Failed to find a NULL terminator when reading a string", stream->diagContext);
        return AVIF_FALSE;
    }

    const char * streamString = (const char *)p;
    size_t stringLen = strlen(streamString);
    stream->offset += stringLen + 1; // update the stream to have read the "whole string" in

    if (output && outputSize) {
        // clamp to our output buffer
        if (stringLen >= outputSize) {
            stringLen = outputSize - 1;
        }
        memcpy(output, streamString, stringLen);
        output[stringLen] = 0;
    }
    return AVIF_TRUE;
}

avifBool avifROStreamReadBoxHeaderPartial(avifROStream * stream, avifBoxHeader * header, avifBool topLevel)
{
    // Section 4.2.2 of ISO/IEC 14496-12.
    size_t startOffset = stream->offset;

    uint32_t smallSize;
    AVIF_CHECK(avifROStreamReadU32(stream, &smallSize));   // unsigned int(32) size;
    AVIF_CHECK(avifROStreamRead(stream, header->type, 4)); // unsigned int(32) type = boxtype;

    uint64_t size = smallSize;
    if (size == 1) {
        AVIF_CHECK(avifROStreamReadU64(stream, &size)); // unsigned int(64) largesize;
    }

    if (!memcmp(header->type, "uuid", 4)) {
        AVIF_CHECK(avifROStreamSkip(stream, 16)); // unsigned int(8) usertype[16] = extended_type;
    }

    size_t bytesRead = stream->offset - startOffset;
    if (size == 0) {
        // Section 4.2.2 of ISO/IEC 14496-12.
        //   if size is 0, then this box shall be in a top-level box (i.e. not contained in another
        //   box), and be the last box in its 'file', and its payload extends to the end of that
        //   enclosing 'file'. This is normally only used for a MediaDataBox.
        if (!topLevel) {
            avifDiagnosticsPrintf(stream->diag, "%s: Non-top-level box with size 0", stream->diagContext);
            return AVIF_FALSE;
        }

        // The given stream may be incomplete and there is no guarantee that sizeHint is available and accurate.
        // Otherwise size could be set to avifROStreamRemainingBytes(stream) + (stream->offset - startOffset) right now.

        // Wait for avifIOReadFunc() to return AVIF_RESULT_OK.
        header->isSizeZeroBox = AVIF_TRUE;
        header->size = 0;
        return AVIF_TRUE;
    }

    if ((size < bytesRead) || ((size - bytesRead) > SIZE_MAX)) {
        avifDiagnosticsPrintf(stream->diag, "%s: Header size overflow check failure", stream->diagContext);
        return AVIF_FALSE;
    }
    header->isSizeZeroBox = AVIF_FALSE;
    header->size = (size_t)(size - bytesRead);
    return AVIF_TRUE;
}

avifBool avifROStreamReadBoxHeader(avifROStream * stream, avifBoxHeader * header)
{
    AVIF_CHECK(avifROStreamReadBoxHeaderPartial(stream, header, /*topLevel=*/AVIF_FALSE));
    if (header->size > avifROStreamRemainingBytes(stream)) {
        avifDiagnosticsPrintf(stream->diag, "%s: Child box too large, possibly truncated data", stream->diagContext);
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

avifBool avifROStreamReadVersionAndFlags(avifROStream * stream, uint8_t * version, uint32_t * flags)
{
    uint8_t versionAndFlags[4];
    AVIF_CHECK(avifROStreamRead(stream, versionAndFlags, 4));
    if (version) {
        *version = versionAndFlags[0];
    }
    if (flags) {
        *flags = (versionAndFlags[1] << 16) + (versionAndFlags[2] << 8) + (versionAndFlags[3] << 0);
    }
    return AVIF_TRUE;
}

avifBool avifROStreamReadAndEnforceVersion(avifROStream * stream, uint8_t enforcedVersion)
{
    uint8_t version;
    AVIF_CHECK(avifROStreamReadVersionAndFlags(stream, &version, NULL));
    if (version != enforcedVersion) {
        avifDiagnosticsPrintf(stream->diag, "%s: Expecting box version %u, got version %u", stream->diagContext, enforcedVersion, version);
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

// ---------------------------------------------------------------------------
// avifRWStream

#define AVIF_STREAM_BUFFER_INCREMENT (1024 * 1024)
static avifResult makeRoom(avifRWStream * stream, size_t size)
{
    size_t neededSize = stream->offset + size;
    size_t newSize = stream->raw->size;
    while (newSize < neededSize) {
        newSize += AVIF_STREAM_BUFFER_INCREMENT;
    }
    return avifRWDataRealloc(stream->raw, newSize);
}

void avifRWStreamStart(avifRWStream * stream, avifRWData * raw)
{
    stream->raw = raw;
    stream->offset = 0;
    stream->numUsedBitsInPartialByte = 0;
}

size_t avifRWStreamOffset(const avifRWStream * stream)
{
    return stream->offset;
}

void avifRWStreamSetOffset(avifRWStream * stream, size_t offset)
{
    stream->offset = offset;
    if (stream->offset > stream->raw->size) {
        stream->offset = stream->raw->size;
    }
}

void avifRWStreamFinishWrite(avifRWStream * stream)
{
    if (stream->raw->size != stream->offset) {
        if (stream->offset) {
            stream->raw->size = stream->offset;
        } else {
            avifRWDataFree(stream->raw);
        }
    }
}

avifResult avifRWStreamWrite(avifRWStream * stream, const void * data, size_t size)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    if (size) {
        AVIF_CHECKRES(makeRoom(stream, size));
        memcpy(stream->raw->data + stream->offset, data, size);
        stream->offset += size;
    }
    return AVIF_RESULT_OK;
}

avifResult avifRWStreamWriteChars(avifRWStream * stream, const char * chars, size_t size)
{
    return avifRWStreamWrite(stream, chars, size);
}

avifResult avifRWStreamWriteFullBox(avifRWStream * stream, const char * type, size_t contentSize, int version, uint32_t flags, avifBoxMarker * marker)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    if (marker) {
        *marker = stream->offset;
    }
    size_t headerSize = sizeof(uint32_t) + 4 /* size of type */;
    if (version != -1) {
        headerSize += 4;
    }

    AVIF_CHECKRES(makeRoom(stream, headerSize));
    memset(stream->raw->data + stream->offset, 0, headerSize);
    uint32_t noSize = avifHTONL((uint32_t)(headerSize + contentSize));
    memcpy(stream->raw->data + stream->offset, &noSize, sizeof(uint32_t));
    memcpy(stream->raw->data + stream->offset + 4, type, 4);
    if (version != -1) {
        stream->raw->data[stream->offset + 8] = (uint8_t)version;
        stream->raw->data[stream->offset + 9] = (uint8_t)((flags >> 16) & 0xff);
        stream->raw->data[stream->offset + 10] = (uint8_t)((flags >> 8) & 0xff);
        stream->raw->data[stream->offset + 11] = (uint8_t)((flags >> 0) & 0xff);
    }
    stream->offset += headerSize;

    return AVIF_RESULT_OK;
}

avifResult avifRWStreamWriteBox(avifRWStream * stream, const char * type, size_t contentSize, avifBoxMarker * marker)
{
    return avifRWStreamWriteFullBox(stream, type, contentSize, -1, 0, marker);
}

void avifRWStreamFinishBox(avifRWStream * stream, avifBoxMarker marker)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    uint32_t noSize = avifHTONL((uint32_t)(stream->offset - marker));
    memcpy(stream->raw->data + marker, &noSize, sizeof(uint32_t));
}

avifResult avifRWStreamWriteU8(avifRWStream * stream, uint8_t v)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    AVIF_CHECKRES(makeRoom(stream, 1));
    stream->raw->data[stream->offset] = v;
    stream->offset += 1;
    return AVIF_RESULT_OK;
}

avifResult avifRWStreamWriteU16(avifRWStream * stream, uint16_t v)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    const size_t size = sizeof(uint16_t);
    AVIF_CHECKRES(makeRoom(stream, size));
    v = avifHTONS(v);
    memcpy(stream->raw->data + stream->offset, &v, size);
    stream->offset += size;
    return AVIF_RESULT_OK;
}

avifResult avifRWStreamWriteU32(avifRWStream * stream, uint32_t v)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    const size_t size = sizeof(uint32_t);
    AVIF_CHECKRES(makeRoom(stream, size));
    v = avifHTONL(v);
    memcpy(stream->raw->data + stream->offset, &v, size);
    stream->offset += size;
    return AVIF_RESULT_OK;
}

avifResult avifRWStreamWriteU64(avifRWStream * stream, uint64_t v)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    const size_t size = sizeof(uint64_t);
    AVIF_CHECKRES(makeRoom(stream, size));
    v = avifHTON64(v);
    memcpy(stream->raw->data + stream->offset, &v, size);
    stream->offset += size;
    return AVIF_RESULT_OK;
}

avifResult avifRWStreamWriteZeros(avifRWStream * stream, size_t byteCount)
{
    assert(stream->numUsedBitsInPartialByte == 0); // Byte alignment is required.
    AVIF_CHECKRES(makeRoom(stream, byteCount));
    memset(stream->raw->data + stream->offset, 0, byteCount);
    stream->offset += byteCount;
    return AVIF_RESULT_OK;
}

avifResult avifRWStreamWriteBits(avifRWStream * stream, uint32_t v, size_t bitCount)
{
    assert(((uint64_t)v >> bitCount) == 0); // (uint32_t >> 32 is undefined behavior)
    while (bitCount) {
        if (stream->numUsedBitsInPartialByte == 0) {
            AVIF_CHECKRES(makeRoom(stream, 1)); // Book a new partial byte in the stream.
            stream->raw->data[stream->offset] = 0;
            stream->offset += 1;
        }
        assert(stream->offset > 0);
        uint8_t * packedBits = stream->raw->data + stream->offset - 1;

        const size_t numBits = AVIF_MIN(bitCount, 8 - stream->numUsedBitsInPartialByte);
        stream->numUsedBitsInPartialByte += numBits;
        bitCount -= numBits;
        // Order the input bits from the most significant bit to the least significant bit.
        // In the case where avifRWStreamWriteBits() is used to write the unsigned integer value v
        // over multiple aligned bytes, this order corresponds to big endianness.
        const uint32_t bits = (v >> bitCount) & ((1 << numBits) - 1);
        // Pack bits starting with the most significant bit of the first output byte.
        // This way, packed bits can be found in the same order in the bit stream.
        *packedBits |= bits << (8 - stream->numUsedBitsInPartialByte);

        if (stream->numUsedBitsInPartialByte == 8) {
            // Start a new partial byte the next time a bit is needed.
            stream->numUsedBitsInPartialByte = 0;
        }
    }
    return AVIF_RESULT_OK;
}

avifResult avifRWStreamWriteVarInt(avifRWStream * stream, uint32_t v)
{
    AVIF_CHECKERR(v < (1u << (VARINT_DEPTH_0 + VARINT_DEPTH_1 + VARINT_DEPTH_2)) + (1u << (VARINT_DEPTH_0 + VARINT_DEPTH_1)) +
                          (1u << VARINT_DEPTH_0),
                  AVIF_RESULT_INVALID_ARGUMENT);

    AVIF_CHECKRES(avifRWStreamWriteBits(stream, v & ((1u << VARINT_DEPTH_0) - 1), VARINT_DEPTH_0)); // value
    v >>= VARINT_DEPTH_0;
    AVIF_CHECKRES(avifRWStreamWriteBits(stream, v > 0, 1)); // extended
    if (v > 0) {
        v -= 1;
        AVIF_CHECKRES(avifRWStreamWriteBits(stream, v & ((1u << VARINT_DEPTH_1) - 1), VARINT_DEPTH_1)); // extension
        v >>= VARINT_DEPTH_1;
        AVIF_CHECKRES(avifRWStreamWriteBits(stream, v > 0, 1)); // extended
        if (v > 0) {
            v -= 1;
            AVIF_CHECKRES(avifRWStreamWriteBits(stream, v, VARINT_DEPTH_2)); // extension
        }
    }
    return AVIF_RESULT_OK;
}
