/*
  zip_algorithm_zstd.c -- zstd (de)compression routines
  Copyright (C) 2020 Dieter Baron and Thomas Klausner

  This file is part of libzip, a library to manipulate ZIP archives.
  The authors can be contacted at <libzip@nih.at>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
  3. The names of the authors may not be used to endorse or promote
     products derived from this software without specific prior
     written permission.

  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "zipint.h"

#include <limits.h>
#include <stdlib.h>
#include <zstd.h>
#include <zstd_errors.h>

struct ctx {
    zip_error_t *error;
    bool compress;
    int compression_flags;
    bool end_of_input;
    ZSTD_DStream *zdstream;
    ZSTD_CStream *zcstream;
    ZSTD_outBuffer out;
    ZSTD_inBuffer in;
};

static zip_uint64_t
maximum_compressed_size(zip_uint64_t uncompressed_size) {
    return ZSTD_compressBound(uncompressed_size);
}


static void *
allocate(bool compress, int compression_flags, zip_error_t *error) {
    struct ctx *ctx;

    /* 0: let zstd choose */
    if (compression_flags < 0 || compression_flags > 9) {
        compression_flags = 0;
    }

    if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
        return NULL;
    }

    ctx->error = error;
    ctx->compress = compress;
    ctx->compression_flags = compression_flags;
    ctx->end_of_input = false;

    ctx->zdstream = NULL;
    ctx->zcstream = NULL;
    ctx->in.src = NULL;
    ctx->in.pos = 0;
    ctx->in.size = 0;
    ctx->out.dst = NULL;
    ctx->out.pos = 0;
    ctx->out.size = 0;

    return ctx;
}


static void *
compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
    return allocate(true, compression_flags, error);
}


static void *
decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
    return allocate(false, compression_flags, error);
}


static void
deallocate(void *ud) {
    struct ctx *ctx = (struct ctx *)ud;
    free(ctx);
}


static zip_uint16_t
general_purpose_bit_flags(void *ud) {
    /* struct ctx *ctx = (struct ctx *)ud; */
    return 0;
}

static int
map_error(size_t ret) {
    switch (ret) {
    case ZSTD_error_no_error:
        return ZIP_ER_OK;

    case ZSTD_error_corruption_detected:
    case ZSTD_error_checksum_wrong:
    case ZSTD_error_dictionary_corrupted:
    case ZSTD_error_dictionary_wrong:
        return ZIP_ER_COMPRESSED_DATA;

    case ZSTD_error_memory_allocation:
        return ZIP_ER_MEMORY;

    case ZSTD_error_parameter_unsupported:
    case ZSTD_error_parameter_outOfBound:
        return ZIP_ER_INVAL;

    default:
        return ZIP_ER_INTERNAL;
    }
}


static bool
start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
    struct ctx *ctx = (struct ctx *)ud;
    ctx->in.src = NULL;
    ctx->in.pos = 0;
    ctx->in.size = 0;
    ctx->out.dst = NULL;
    ctx->out.pos = 0;
    ctx->out.size = 0;
    if (ctx->compress) {
        size_t ret;
        ctx->zcstream = ZSTD_createCStream();
        if (ctx->zcstream == NULL) {
            zip_error_set(ctx->error, ZIP_ER_MEMORY, 0);
            return false;
        }
        ret = ZSTD_initCStream(ctx->zcstream, ctx->compression_flags);
        if (ZSTD_isError(ret)) {
            zip_error_set(ctx->error, ZIP_ER_ZLIB, map_error(ret));
            return false;
        }
    }
    else {
        ctx->zdstream = ZSTD_createDStream();
        if (ctx->zdstream == NULL) {
            zip_error_set(ctx->error, ZIP_ER_MEMORY, 0);
            return false;
        }
    }

    return true;
}


static bool
end(void *ud) {
    struct ctx *ctx = (struct ctx *)ud;
    size_t ret;

    if (ctx->compress) {
        ret = ZSTD_freeCStream(ctx->zcstream);
        ctx->zcstream = NULL;
    }
    else {
        ret = ZSTD_freeDStream(ctx->zdstream);
        ctx->zdstream = NULL;
    }

    if (ZSTD_isError(ret)) {
        zip_error_set(ctx->error, map_error(ret), 0);
        return false;
    }

    return true;
}


static bool
input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
    struct ctx *ctx = (struct ctx *)ud;
    if (length > SIZE_MAX || ctx->in.pos != ctx->in.size) {
        zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
        return false;
    }
    ctx->in.src = (const void *)data;
    ctx->in.size = (size_t)length;
    ctx->in.pos = 0;
    return true;
}


static void
end_of_input(void *ud) {
    struct ctx *ctx = (struct ctx *)ud;

    ctx->end_of_input = true;
}


static zip_compression_status_t
process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
    struct ctx *ctx = (struct ctx *)ud;

    size_t ret;

    if (ctx->in.pos == ctx->in.size && !ctx->end_of_input) {
        *length = 0;
        return ZIP_COMPRESSION_NEED_DATA;
    }

    ctx->out.dst = data;
    ctx->out.pos = 0;
    ctx->out.size = ZIP_MIN(SIZE_MAX, *length);

    if (ctx->compress) {
        if (ctx->in.pos == ctx->in.size && ctx->end_of_input) {
            ret = ZSTD_endStream(ctx->zcstream, &ctx->out);
            if (ret == 0) {
                *length = ctx->out.pos;
                return ZIP_COMPRESSION_END;
            }
        }
        else {
            ret = ZSTD_compressStream(ctx->zcstream, &ctx->out, &ctx->in);
        }
    }
    else {
        ret = ZSTD_decompressStream(ctx->zdstream, &ctx->out, &ctx->in);
    }
    if (ZSTD_isError(ret)) {
        zip_error_set(ctx->error, map_error(ret), 0);
        return ZIP_COMPRESSION_ERROR;
    }

    *length = ctx->out.pos;
    if (ctx->in.pos == ctx->in.size) {
        return ZIP_COMPRESSION_NEED_DATA;
    }

    return ZIP_COMPRESSION_OK;
}

/* Version Required should be set to 63 (6.3) because this compression
   method was only defined in appnote.txt version 6.3.7, but Winzip
   does not unpack it if the value is not 20. */

/* clang-format off */

zip_compression_algorithm_t zip_algorithm_zstd_compress = {
    maximum_compressed_size,
    compress_allocate,
    deallocate,
    general_purpose_bit_flags,
    20,
    start,
    end,
    input,
    end_of_input,
    process
};


zip_compression_algorithm_t zip_algorithm_zstd_decompress = {
    maximum_compressed_size,
    decompress_allocate,
    deallocate,
    general_purpose_bit_flags,
    20,
    start,
    end,
    input,
    end_of_input,
    process
};

/* clang-format on */
