/*
  zip_source_compress.c -- (de)compression routines
  Copyright (C) 2017-2021 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 <stdlib.h>
#include <string.h>

#include "zipint.h"

struct context {
    zip_error_t error;

    bool end_of_input;
    bool end_of_stream;
    bool can_store;
    bool is_stored; /* only valid if end_of_stream is true */
    bool compress;
    zip_int32_t method;

    zip_uint64_t size;
    zip_int64_t first_read;
    zip_uint8_t buffer[BUFSIZE];

    zip_compression_algorithm_t *algorithm;
    void *ud;
};


struct implementation {
    zip_uint16_t method;
    zip_compression_algorithm_t *compress;
    zip_compression_algorithm_t *decompress;
};

static struct implementation implementations[] = {
    {ZIP_CM_DEFLATE, &zip_algorithm_deflate_compress, &zip_algorithm_deflate_decompress},
#if defined(HAVE_LIBBZ2)
    {ZIP_CM_BZIP2, &zip_algorithm_bzip2_compress, &zip_algorithm_bzip2_decompress},
#endif
#if defined(HAVE_LIBLZMA)
    {ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
    /*  Disabled - because 7z isn't able to unpack ZIP+LZMA2
        archives made this way - and vice versa.

        {ZIP_CM_LZMA2, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
    */
    {ZIP_CM_XZ, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
#endif
#if defined(HAVE_LIBZSTD)
    {ZIP_CM_ZSTD, &zip_algorithm_zstd_compress, &zip_algorithm_zstd_decompress},
#endif

};

static size_t implementations_size = sizeof(implementations) / sizeof(implementations[0]);

static zip_source_t *compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags);
static zip_int64_t compress_callback(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
static void context_free(struct context *ctx);
static struct context *context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm);
static zip_int64_t compress_read(zip_source_t *, struct context *, void *, zip_uint64_t);

zip_compression_algorithm_t *
_zip_get_compression_algorithm(zip_int32_t method, bool compress) {
    size_t i;
    zip_uint16_t real_method = ZIP_CM_ACTUAL(method);

    for (i = 0; i < implementations_size; i++) {
        if (implementations[i].method == real_method) {
            if (compress) {
                return implementations[i].compress;
            }
            else {
                return implementations[i].decompress;
            }
        }
    }

    return NULL;
}

ZIP_EXTERN int
zip_compression_method_supported(zip_int32_t method, int compress) {
    if (method == ZIP_CM_STORE) {
        return 1;
    }
    return _zip_get_compression_algorithm(method, compress) != NULL;
}

zip_source_t *
zip_source_compress(zip_t *za, zip_source_t *src, zip_int32_t method, int compression_flags) {
    return compression_source_new(za, src, method, true, compression_flags);
}

zip_source_t *
zip_source_decompress(zip_t *za, zip_source_t *src, zip_int32_t method) {
    return compression_source_new(za, src, method, false, 0);
}


static zip_source_t *
compression_source_new(zip_t *za, zip_source_t *src, zip_int32_t method, bool compress, int compression_flags) {
    struct context *ctx;
    zip_source_t *s2;
    zip_compression_algorithm_t *algorithm = NULL;

    if (src == NULL) {
        zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return NULL;
    }

    if ((algorithm = _zip_get_compression_algorithm(method, compress)) == NULL) {
        zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
        return NULL;
    }

    if ((ctx = context_new(method, compress, compression_flags, algorithm)) == NULL) {
        zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
        return NULL;
    }

    if ((s2 = zip_source_layered(za, src, compress_callback, ctx)) == NULL) {
        context_free(ctx);
        return NULL;
    }

    return s2;
}


static struct context *
context_new(zip_int32_t method, bool compress, int compression_flags, zip_compression_algorithm_t *algorithm) {
    struct context *ctx;

    if ((ctx = (struct context *)malloc(sizeof(*ctx))) == NULL) {
        return NULL;
    }
    zip_error_init(&ctx->error);
    ctx->can_store = compress ? ZIP_CM_IS_DEFAULT(method) : false;
    ctx->algorithm = algorithm;
    ctx->method = method;
    ctx->compress = compress;
    ctx->end_of_input = false;
    ctx->end_of_stream = false;
    ctx->is_stored = false;

    if ((ctx->ud = ctx->algorithm->allocate(ZIP_CM_ACTUAL(method), compression_flags, &ctx->error)) == NULL) {
        zip_error_fini(&ctx->error);
        free(ctx);
        return NULL;
    }

    return ctx;
}


static void
context_free(struct context *ctx) {
    if (ctx == NULL) {
        return;
    }

    ctx->algorithm->deallocate(ctx->ud);
    zip_error_fini(&ctx->error);

    free(ctx);
}


static zip_int64_t
compress_read(zip_source_t *src, struct context *ctx, void *data, zip_uint64_t len) {
    zip_compression_status_t ret;
    bool end;
    zip_int64_t n;
    zip_uint64_t out_offset;
    zip_uint64_t out_len;

    if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK) {
        return -1;
    }

    if (len == 0 || ctx->end_of_stream) {
        return 0;
    }

    out_offset = 0;

    end = false;
    while (!end && out_offset < len) {
        out_len = len - out_offset;
        ret = ctx->algorithm->process(ctx->ud, (zip_uint8_t *)data + out_offset, &out_len);

        if (ret != ZIP_COMPRESSION_ERROR) {
            out_offset += out_len;
        }

        switch (ret) {
        case ZIP_COMPRESSION_END:
            ctx->end_of_stream = true;

            if (!ctx->end_of_input) {
                /* TODO: garbage after stream, or compression ended before all data read */
            }

            if (ctx->first_read < 0) {
                /* we got end of processed stream before reading any input data */
                zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
                end = true;
                break;
            }
            if (ctx->can_store && (zip_uint64_t)ctx->first_read <= out_offset) {
                ctx->is_stored = true;
                ctx->size = (zip_uint64_t)ctx->first_read;
                memcpy(data, ctx->buffer, ctx->size);
                return (zip_int64_t)ctx->size;
            }
            end = true;
            break;

        case ZIP_COMPRESSION_OK:
            break;

        case ZIP_COMPRESSION_NEED_DATA:
            if (ctx->end_of_input) {
                /* TODO: error: stream not ended, but no more input */
                end = true;
                break;
            }

            if ((n = zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
                _zip_error_set_from_source(&ctx->error, src);
                end = true;
                break;
            }
            else if (n == 0) {
                ctx->end_of_input = true;
                ctx->algorithm->end_of_input(ctx->ud);
                if (ctx->first_read < 0) {
                    ctx->first_read = 0;
                }
            }
            else {
                if (ctx->first_read >= 0) {
                    /* we overwrote a previously filled ctx->buffer */
                    ctx->can_store = false;
                }
                else {
                    ctx->first_read = n;
                }

                ctx->algorithm->input(ctx->ud, ctx->buffer, (zip_uint64_t)n);
            }
            break;

        case ZIP_COMPRESSION_ERROR:
            /* error set by algorithm */
            if (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) {
                zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
            }
            end = true;
            break;
        }
    }

    if (out_offset > 0) {
        ctx->can_store = false;
        ctx->size += out_offset;
        return (zip_int64_t)out_offset;
    }

    return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
}


static zip_int64_t
compress_callback(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
    struct context *ctx;

    ctx = (struct context *)ud;

    switch (cmd) {
    case ZIP_SOURCE_OPEN: {
        zip_stat_t st;
        zip_file_attributes_t attributes;
        
        ctx->size = 0;
        ctx->end_of_input = false;
        ctx->end_of_stream = false;
        ctx->is_stored = false;
        ctx->first_read = -1;
        
        if (zip_source_stat(src, &st) < 0 || zip_source_get_file_attributes(src, &attributes) < 0) {
            _zip_error_set_from_source(&ctx->error, src);
            return -1;
        }

        if (!ctx->algorithm->start(ctx->ud, &st, &attributes)) {
            return -1;
        }

        return 0;
    }

    case ZIP_SOURCE_READ:
        return compress_read(src, ctx, data, len);

    case ZIP_SOURCE_CLOSE:
        if (!ctx->algorithm->end(ctx->ud)) {
            return -1;
        }
        return 0;

    case ZIP_SOURCE_STAT: {
        zip_stat_t *st;

        st = (zip_stat_t *)data;

        if (ctx->compress) {
            if (ctx->end_of_stream) {
                st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_ACTUAL(ctx->method);
                st->comp_size = ctx->size;
                st->valid |= ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD;
            }
            else {
                st->valid &= ~(ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD);
            }
        }
        else {
            st->comp_method = ZIP_CM_STORE;
            st->valid |= ZIP_STAT_COMP_METHOD;
            if (ctx->end_of_stream) {
                st->size = ctx->size;
                st->valid |= ZIP_STAT_SIZE;
            }
        }
    }
        return 0;

    case ZIP_SOURCE_ERROR:
        return zip_error_to_data(&ctx->error, data, len);

    case ZIP_SOURCE_FREE:
        context_free(ctx);
        return 0;

    case ZIP_SOURCE_GET_FILE_ATTRIBUTES: {
        zip_file_attributes_t *attributes = (zip_file_attributes_t *)data;

        if (len < sizeof(*attributes)) {
            zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
            return -1;
        }

        attributes->valid |= ZIP_FILE_ATTRIBUTES_VERSION_NEEDED | ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS;
        attributes->version_needed = ctx->algorithm->version_needed;
        attributes->general_purpose_bit_mask = ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
        attributes->general_purpose_bit_flags = (ctx->is_stored ? 0 : ctx->algorithm->general_purpose_bit_flags(ctx->ud));

        return sizeof(*attributes);
    }

    case ZIP_SOURCE_SUPPORTS:
        return ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_GET_FILE_ATTRIBUTES, -1);

    default:
        zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
        return -1;
    }
}
