/*
  zip_source_compress.c -- (de)compression routines
  Copyright (C) 2017-2019 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)
    /*  Disabled - because 7z isn't able to unpack ZIP+LZMA ZIP+LZMA2
        archives made this way - and vice versa.

        {ZIP_CM_LZMA, &zip_algorithm_xz_compress, &zip_algorithm_xz_decompress},
        {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:
        ctx->size = 0;
        ctx->end_of_input = false;
        ctx->end_of_stream = false;
        ctx->is_stored = false;
        ctx->first_read = -1;

        if (!ctx->algorithm->start(ctx->ud)) {
            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;
            }
            else {
                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;
    }
}
