/*
  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;
    }
}
