/*
 * Copyright (c) 2016-2020, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under both the BSD-style license (found in the
 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
 * in the COPYING file in the root directory of this source tree).
 * You may select, at your option, one of the above-listed licenses.
 */

/**
 * This fuzz target makes sure that whenever a compression dictionary can be
 * loaded, the data can be round tripped.
 */

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "fuzz_helpers.h"
#include "zstd_helpers.h"
#include "fuzz_data_producer.h"

/**
 * Compresses the data and returns the compressed size or an error.
 */
static size_t compress(void* compressed, size_t compressedCapacity,
                       void const* source, size_t sourceSize,
                       void const* dict, size_t dictSize,
                       ZSTD_dictLoadMethod_e dictLoadMethod,
                       ZSTD_dictContentType_e dictContentType,
                       int const refPrefix)
{
    ZSTD_CCtx* cctx = ZSTD_createCCtx();
    if (refPrefix)
        FUZZ_ZASSERT(ZSTD_CCtx_refPrefix_advanced(
            cctx, dict, dictSize, dictContentType));
    else 
        FUZZ_ZASSERT(ZSTD_CCtx_loadDictionary_advanced(
            cctx, dict, dictSize, dictLoadMethod, dictContentType));
    size_t const compressedSize = ZSTD_compress2(
            cctx, compressed, compressedCapacity, source, sourceSize);
    ZSTD_freeCCtx(cctx);
    return compressedSize;
}

static size_t decompress(void* result, size_t resultCapacity,
                         void const* compressed, size_t compressedSize,
                         void const* dict, size_t dictSize,
                       ZSTD_dictLoadMethod_e dictLoadMethod,
                         ZSTD_dictContentType_e dictContentType,
                         int const refPrefix)
{
    ZSTD_DCtx* dctx = ZSTD_createDCtx();
    if (refPrefix)
        FUZZ_ZASSERT(ZSTD_DCtx_refPrefix_advanced(
            dctx, dict, dictSize, dictContentType));
    else
        FUZZ_ZASSERT(ZSTD_DCtx_loadDictionary_advanced(
            dctx, dict, dictSize, dictLoadMethod, dictContentType));
    size_t const resultSize = ZSTD_decompressDCtx(
            dctx, result, resultCapacity, compressed, compressedSize);
    FUZZ_ZASSERT(resultSize);
    ZSTD_freeDCtx(dctx);
    return resultSize;
}

int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{
    FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
    int const refPrefix = FUZZ_dataProducer_uint32Range(producer, 0, 1) != 0;
    ZSTD_dictLoadMethod_e const dlm =
    size = FUZZ_dataProducer_uint32Range(producer, 0, 1);
    ZSTD_dictContentType_e const dct =
            FUZZ_dataProducer_uint32Range(producer, 0, 2);
    size = FUZZ_dataProducer_remainingBytes(producer);

    DEBUGLOG(2, "Dict load method %d", dlm);
    DEBUGLOG(2, "Dict content type %d", dct);
    DEBUGLOG(2, "Dict size %u", (unsigned)size);

    void* const rBuf = FUZZ_malloc(size);
    size_t const cBufSize = ZSTD_compressBound(size);
    void* const cBuf = FUZZ_malloc(cBufSize);

    size_t const cSize =
            compress(cBuf, cBufSize, src, size, src, size, dlm, dct, refPrefix);
    /* compression failing is okay */
    if (ZSTD_isError(cSize)) {
      FUZZ_ASSERT_MSG(dct != ZSTD_dct_rawContent, "Raw must always succeed!");
      goto out;
    }
    size_t const rSize =
            decompress(rBuf, size, cBuf, cSize, src, size, dlm, dct, refPrefix);
    FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size");
    FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!");

out:
    free(cBuf);
    free(rBuf);
    FUZZ_dataProducer_free(producer);
    return 0;
}
