/*
  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 int
compression_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,
    compression_flags,
    start,
    end,
    input,
    end_of_input,
    process
};


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

/* clang-format on */
