// LZ4 API example : Dictionary Random Access

#if defined(_MSC_VER) && (_MSC_VER <= 1800)  /* Visual Studio <= 2013 */
#  define _CRT_SECURE_NO_WARNINGS
#  define snprintf sprintf_s
#endif
#include "lz4.h"

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#define MIN(x, y)  ((x) < (y) ? (x) : (y))

enum {
    BLOCK_BYTES = 1024,  /* 1 KiB of uncompressed data in a block */
    DICTIONARY_BYTES = 1024, /* Load a 1 KiB dictionary */
    MAX_BLOCKS = 1024 /* For simplicity of implementation */
};

/**
 * Magic bytes for this test case.
 * This is not a great magic number because it is a common word in ASCII.
 * However, it is important to have some versioning system in your format.
 */
const char kTestMagic[] = { 'T', 'E', 'S', 'T' };


void write_int(FILE* fp, int i) {
    size_t written = fwrite(&i, sizeof(i), 1, fp);
    if (written != 1) { exit(10); }
}

void write_bin(FILE* fp, const void* array, size_t arrayBytes) {
    size_t written = fwrite(array, 1, arrayBytes, fp);
    if (written != arrayBytes) { exit(11); }
}

void read_int(FILE* fp, int* i) {
    size_t read = fread(i, sizeof(*i), 1, fp);
    if (read != 1) { exit(12); }
}

size_t read_bin(FILE* fp, void* array, size_t arrayBytes) {
    size_t read = fread(array, 1, arrayBytes, fp);
    if (ferror(fp)) { exit(12); }
    return read;
}

void seek_bin(FILE* fp, long offset, int origin) {
    if (fseek(fp, offset, origin)) { exit(14); }
}


void test_compress(FILE* outFp, FILE* inpFp, void *dict, int dictSize)
{
    LZ4_stream_t lz4Stream_body;
    LZ4_stream_t* lz4Stream = &lz4Stream_body;

    char inpBuf[BLOCK_BYTES];
    int offsets[MAX_BLOCKS];
    int *offsetsEnd = offsets;


    LZ4_initStream(lz4Stream, sizeof(*lz4Stream));

    /* Write header magic */
    write_bin(outFp, kTestMagic, sizeof(kTestMagic));

    *offsetsEnd++ = sizeof(kTestMagic);
    /* Write compressed data blocks.  Each block contains BLOCK_BYTES of plain
       data except possibly the last. */
    for(;;) {
        const int inpBytes = (int) read_bin(inpFp, inpBuf, BLOCK_BYTES);
        if(0 == inpBytes) {
            break;
        }

        /* Forget previously compressed data and load the dictionary */
        LZ4_loadDict(lz4Stream, (const char*) dict, dictSize);
        {
            char cmpBuf[LZ4_COMPRESSBOUND(BLOCK_BYTES)];
            const int cmpBytes = LZ4_compress_fast_continue(
                lz4Stream, inpBuf, cmpBuf, inpBytes, sizeof(cmpBuf), 1);
            if(cmpBytes <= 0) { exit(1); }
            write_bin(outFp, cmpBuf, (size_t)cmpBytes);
            /* Keep track of the offsets */
            *offsetsEnd = *(offsetsEnd - 1) + cmpBytes;
            ++offsetsEnd;
        }
        if (offsetsEnd - offsets > MAX_BLOCKS) { exit(2); }
    }
    /* Write the tailing jump table */
    {
        int *ptr = offsets;
        while (ptr != offsetsEnd) {
            write_int(outFp, *ptr++);
        }
        write_int(outFp, (int) (offsetsEnd - offsets));
    }
}


void test_decompress(FILE* outFp, FILE* inpFp, void *dict, int dictSize, int offset, int length)
{
    LZ4_streamDecode_t lz4StreamDecode_body;
    LZ4_streamDecode_t* lz4StreamDecode = &lz4StreamDecode_body;

    /* The blocks [currentBlock, endBlock) contain the data we want */
    int currentBlock = offset / BLOCK_BYTES;
    int endBlock = ((offset + length - 1) / BLOCK_BYTES) + 1;

    char decBuf[BLOCK_BYTES];
    int offsets[MAX_BLOCKS];

    /* Special cases */
    if (length == 0) { return; }

    /* Read the magic bytes */
    {
        char magic[sizeof(kTestMagic)];
        size_t read = read_bin(inpFp, magic, sizeof(magic));
        if (read != sizeof(magic)) { exit(1); }
        if (memcmp(kTestMagic, magic, sizeof(magic))) { exit(2); }
    }

    /* Read the offsets tail */
    {
        int numOffsets;
        int block;
        int *offsetsPtr = offsets;
        seek_bin(inpFp, -4, SEEK_END);
        read_int(inpFp, &numOffsets);
        if (numOffsets <= endBlock) { exit(3); }
        seek_bin(inpFp, -4 * (numOffsets + 1), SEEK_END);
        for (block = 0; block <= endBlock; ++block) {
            read_int(inpFp, offsetsPtr++);
        }
    }
    /* Seek to the first block to read */
    seek_bin(inpFp, offsets[currentBlock], SEEK_SET);
    offset = offset % BLOCK_BYTES;

    /* Start decoding */
    for(; currentBlock < endBlock; ++currentBlock) {
        char cmpBuf[LZ4_COMPRESSBOUND(BLOCK_BYTES)];
        /* The difference in offsets is the size of the block */
        int  cmpBytes = offsets[currentBlock + 1] - offsets[currentBlock];
        {
            const size_t read = read_bin(inpFp, cmpBuf, (size_t)cmpBytes);
            if(read != (size_t)cmpBytes) { exit(4); }
        }

        /* Load the dictionary */
        LZ4_setStreamDecode(lz4StreamDecode, (const char*) dict, dictSize);
        {
            const int decBytes = LZ4_decompress_safe_continue(
                lz4StreamDecode, cmpBuf, decBuf, cmpBytes, BLOCK_BYTES);
            if(decBytes <= 0) { exit(5); }
            {
                /* Write out the part of the data we care about */
                int blockLength = MIN(length, (decBytes - offset));
                write_bin(outFp, decBuf + offset, (size_t)blockLength);
                offset = 0;
                length -= blockLength;
            }
        }
    }
}


int compare(FILE* fp0, FILE* fp1, int length)
{
    int result = 0;

    while(0 == result) {
        char b0[4096];
        char b1[4096];
        const size_t r0 = read_bin(fp0, b0, MIN(length, (int)sizeof(b0)));
        const size_t r1 = read_bin(fp1, b1, MIN(length, (int)sizeof(b1)));

        result = (int) r0 - (int) r1;

        if(0 == r0 || 0 == r1) {
            break;
        }
        if(0 == result) {
            result = memcmp(b0, b1, r0);
        }
        length -= r0;
    }

    return result;
}


int main(int argc, char* argv[])
{
    char inpFilename[256] = { 0 };
    char lz4Filename[256] = { 0 };
    char decFilename[256] = { 0 };
    char dictFilename[256] = { 0 };
    int offset;
    int length;
    char dict[DICTIONARY_BYTES];
    int dictSize;

    if(argc < 5) {
        printf("Usage: %s input dictionary offset length", argv[0]);
        return 0;
    }

    snprintf(inpFilename, 256, "%s", argv[1]);
    snprintf(lz4Filename, 256, "%s.lz4s-%d", argv[1], BLOCK_BYTES);
    snprintf(decFilename, 256, "%s.lz4s-%d.dec", argv[1], BLOCK_BYTES);
    snprintf(dictFilename, 256, "%s", argv[2]);
    offset = atoi(argv[3]);
    length = atoi(argv[4]);

    printf("inp    = [%s]\n", inpFilename);
    printf("lz4    = [%s]\n", lz4Filename);
    printf("dec    = [%s]\n", decFilename);
    printf("dict   = [%s]\n", dictFilename);
    printf("offset = [%d]\n", offset);
    printf("length = [%d]\n", length);

    /* Load dictionary */
    {
        FILE* dictFp = fopen(dictFilename, "rb");
        dictSize = (int)read_bin(dictFp, dict, DICTIONARY_BYTES);
        fclose(dictFp);
    }

    /* compress */
    {
        FILE* inpFp = fopen(inpFilename, "rb");
        FILE* outFp = fopen(lz4Filename, "wb");

        printf("compress : %s -> %s\n", inpFilename, lz4Filename);
        test_compress(outFp, inpFp, dict, dictSize);
        printf("compress : done\n");

        fclose(outFp);
        fclose(inpFp);
    }

    /* decompress */
    {
        FILE* inpFp = fopen(lz4Filename, "rb");
        FILE* outFp = fopen(decFilename, "wb");

        printf("decompress : %s -> %s\n", lz4Filename, decFilename);
        test_decompress(outFp, inpFp, dict, DICTIONARY_BYTES, offset, length);
        printf("decompress : done\n");

        fclose(outFp);
        fclose(inpFp);
    }

    /* verify */
    {
        FILE* inpFp = fopen(inpFilename, "rb");
        FILE* decFp = fopen(decFilename, "rb");
        seek_bin(inpFp, offset, SEEK_SET);

        printf("verify : %s <-> %s\n", inpFilename, decFilename);
        const int cmp = compare(inpFp, decFp, length);
        if(0 == cmp) {
            printf("verify : OK\n");
        } else {
            printf("verify : NG\n");
        }

        fclose(decFp);
        fclose(inpFp);
    }

    return 0;
}
