/*
  zip_algorithm_bzip2.c -- bzip2 (de)compression routines
  Copyright (C) 2017 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"

#if defined(HAVE_LIBBZ2)

#include <bzlib.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;
    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) {
	/* TODO: use ctx->compression_flags */
	ret = BZ2_bzCompressInit(&ctx->zstr, 9, 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;

    /* TODO: can this fail? */
    if (ctx->compress) {
	BZ2_bzCompressEnd(&ctx->zstr);
    }
    else {
	BZ2_bzDecompressEnd(&ctx->zstr);
    }

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


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

#else

static int dummy;

#endif /* HAVE_LIBBZ2 */
