/*
  zip_algorithm_bzip2.c -- bzip2 (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 "zipint.h"

#include <bzlib.h>
#include <limits.h>
#include <stdlib.h>

struct ctx {
    zip_error_t *error;
    bool compress;
    int compression_flags;
    bool end_of_input;
    bz_stream zstr;
};


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

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

    ctx->error = error;
    ctx->compress = compress;
    ctx->compression_flags = compression_flags;
    if (ctx->compression_flags < 1 || ctx->compression_flags > 9) {
	ctx->compression_flags = 9;
    }
    ctx->end_of_input = false;

    ctx->zstr.bzalloc = NULL;
    ctx->zstr.bzfree = NULL;
    ctx->zstr.opaque = NULL;

    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) {
    return 0;
}


static int
map_error(int ret) {
    switch (ret) {
    case BZ_FINISH_OK:
    case BZ_FLUSH_OK:
    case BZ_OK:
    case BZ_RUN_OK:
    case BZ_STREAM_END:
	return ZIP_ER_OK;

    case BZ_DATA_ERROR:
    case BZ_DATA_ERROR_MAGIC:
    case BZ_UNEXPECTED_EOF:
	return ZIP_ER_COMPRESSED_DATA;

    case BZ_MEM_ERROR:
	return ZIP_ER_MEMORY;

    case BZ_PARAM_ERROR:
	return ZIP_ER_INVAL;

    case BZ_CONFIG_ERROR: /* actually, bzip2 miscompiled */
    case BZ_IO_ERROR:
    case BZ_OUTBUFF_FULL:
    case BZ_SEQUENCE_ERROR:
	return ZIP_ER_INTERNAL;

    default:
	return ZIP_ER_INTERNAL;
    }
}

static bool
start(void *ud) {
    struct ctx *ctx = (struct ctx *)ud;
    int ret;

    ctx->zstr.avail_in = 0;
    ctx->zstr.next_in = NULL;
    ctx->zstr.avail_out = 0;
    ctx->zstr.next_out = NULL;

    if (ctx->compress) {
	ret = BZ2_bzCompressInit(&ctx->zstr, ctx->compression_flags, 0, 30);
    }
    else {
	ret = BZ2_bzDecompressInit(&ctx->zstr, 0, 0);
    }

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

    return true;
}


static bool
end(void *ud) {
    struct ctx *ctx = (struct ctx *)ud;
    int err;

    if (ctx->compress) {
	err = BZ2_bzCompressEnd(&ctx->zstr);
    }
    else {
	err = BZ2_bzDecompressEnd(&ctx->zstr);
    }

    if (err != BZ_OK) {
	zip_error_set(ctx->error, map_error(err), 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 > UINT_MAX || ctx->zstr.avail_in > 0) {
	zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
	return false;
    }

    ctx->zstr.avail_in = (unsigned int)length;
    ctx->zstr.next_in = (char *)data;

    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;

    int ret;

    if (ctx->zstr.avail_in == 0 && !ctx->end_of_input) {
	*length = 0;
	return ZIP_COMPRESSION_NEED_DATA;
    }

    ctx->zstr.avail_out = (unsigned int)ZIP_MIN(UINT_MAX, *length);
    ctx->zstr.next_out = (char *)data;

    if (ctx->compress) {
	ret = BZ2_bzCompress(&ctx->zstr, ctx->end_of_input ? BZ_FINISH : BZ_RUN);
    }
    else {
	ret = BZ2_bzDecompress(&ctx->zstr);
    }

    *length = *length - ctx->zstr.avail_out;

    switch (ret) {
    case BZ_FINISH_OK: /* compression */
	return ZIP_COMPRESSION_OK;

    case BZ_OK:     /* decompression */
    case BZ_RUN_OK: /* compression */
	if (ctx->zstr.avail_in == 0) {
	    return ZIP_COMPRESSION_NEED_DATA;
	}
	return ZIP_COMPRESSION_OK;

    case BZ_STREAM_END:
	return ZIP_COMPRESSION_END;

    default:
	zip_error_set(ctx->error, map_error(ret), 0);
	return ZIP_COMPRESSION_ERROR;
    }
}

/* clang-format off */

zip_compression_algorithm_t zip_algorithm_bzip2_compress = {
    compress_allocate,
    deallocate,
    general_purpose_bit_flags,
    46,
    start,
    end,
    input,
    end_of_input,
    process
};


zip_compression_algorithm_t zip_algorithm_bzip2_decompress = {
    decompress_allocate,
    deallocate,
    general_purpose_bit_flags,
    46,
    start,
    end,
    input,
    end_of_input,
    process
};

/* clang-format on */
