/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include <zlib.h>

#include "zstream.h"
#include "buffer.h"

#define ZSTREAM_BUFFER_SIZE (1024 * 1024)
#define ZSTREAM_BUFFER_MIN_EXTRA 8

static int zstream_seterr(git_zstream *zs)
{
	if (zs->zerr == Z_OK || zs->zerr == Z_STREAM_END)
		return 0;

	if (zs->zerr == Z_MEM_ERROR)
		giterr_set_oom();
	else if (zs->z.msg)
		giterr_set_str(GITERR_ZLIB, zs->z.msg);
	else
		giterr_set(GITERR_ZLIB, "unknown compression error");

	return -1;
}

int git_zstream_init(git_zstream *zstream, git_zstream_t type)
{
	zstream->type = type;

	if (zstream->type == GIT_ZSTREAM_INFLATE)
		zstream->zerr = inflateInit(&zstream->z);
	else
		zstream->zerr = deflateInit(&zstream->z, Z_DEFAULT_COMPRESSION);
	return zstream_seterr(zstream);
}

void git_zstream_free(git_zstream *zstream)
{
	if (zstream->type == GIT_ZSTREAM_INFLATE)
		inflateEnd(&zstream->z);
	else
		deflateEnd(&zstream->z);
}

void git_zstream_reset(git_zstream *zstream)
{
	if (zstream->type == GIT_ZSTREAM_INFLATE)
		inflateReset(&zstream->z);
	else
		deflateReset(&zstream->z);
	zstream->in = NULL;
	zstream->in_len = 0;
	zstream->zerr = Z_STREAM_END;
}

int git_zstream_set_input(git_zstream *zstream, const void *in, size_t in_len)
{
	zstream->in = in;
	zstream->in_len = in_len;
	zstream->zerr = Z_OK;
	return 0;
}

bool git_zstream_done(git_zstream *zstream)
{
	return (!zstream->in_len && zstream->zerr == Z_STREAM_END);
}

size_t git_zstream_suggest_output_len(git_zstream *zstream)
{
	if (zstream->in_len > ZSTREAM_BUFFER_SIZE)
		return ZSTREAM_BUFFER_SIZE;
	else if (zstream->in_len > ZSTREAM_BUFFER_MIN_EXTRA)
		return zstream->in_len;
	else
		return ZSTREAM_BUFFER_MIN_EXTRA;
}

int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream)
{
	int zflush = Z_FINISH;
	size_t out_remain = *out_len;

	if (zstream->in_len && zstream->zerr == Z_STREAM_END) {
		giterr_set(GITERR_ZLIB, "zlib input had trailing garbage");
		return -1;
	}

	while (out_remain > 0 && zstream->zerr != Z_STREAM_END) {
		size_t out_queued, in_queued, out_used, in_used;

		/* set up in data */
		zstream->z.next_in  = (Bytef *)zstream->in;
		zstream->z.avail_in = (uInt)zstream->in_len;
		if ((size_t)zstream->z.avail_in != zstream->in_len) {
			zstream->z.avail_in = INT_MAX;
			zflush = Z_NO_FLUSH;
		} else {
			zflush = Z_FINISH;
		}
		in_queued = (size_t)zstream->z.avail_in;

		/* set up out data */
		zstream->z.next_out = out;
		zstream->z.avail_out = (uInt)out_remain;
		if ((size_t)zstream->z.avail_out != out_remain)
			zstream->z.avail_out = INT_MAX;
		out_queued = (size_t)zstream->z.avail_out;

		/* compress next chunk */
		if (zstream->type == GIT_ZSTREAM_INFLATE)
			zstream->zerr = inflate(&zstream->z, zflush);
		else
			zstream->zerr = deflate(&zstream->z, zflush);

		if (zstream->zerr == Z_STREAM_ERROR)
			return zstream_seterr(zstream);

		out_used = (out_queued - zstream->z.avail_out);
		out_remain -= out_used;
		out = ((char *)out) + out_used;

		in_used = (in_queued - zstream->z.avail_in);
		zstream->in_len -= in_used;
		zstream->in += in_used;
	}

	/* either we finished the input or we did not flush the data */
	assert(zstream->in_len > 0 || zflush == Z_FINISH);

	/* set out_size to number of bytes actually written to output */
	*out_len = *out_len - out_remain;

	return 0;
}

static int zstream_buf(git_buf *out, const void *in, size_t in_len, git_zstream_t type)
{
	git_zstream zs = GIT_ZSTREAM_INIT;
	int error = 0;

	if ((error = git_zstream_init(&zs, type)) < 0)
		return error;

	if ((error = git_zstream_set_input(&zs, in, in_len)) < 0)
		goto done;

	while (!git_zstream_done(&zs)) {
		size_t step = git_zstream_suggest_output_len(&zs), written;

		if ((error = git_buf_grow_by(out, step)) < 0)
			goto done;

		written = out->asize - out->size;

		if ((error = git_zstream_get_output(
				out->ptr + out->size, &written, &zs)) < 0)
			goto done;

		out->size += written;
	}

	/* NULL terminate for consistency if possible */
	if (out->size < out->asize)
		out->ptr[out->size] = '\0';

done:
	git_zstream_free(&zs);
	return error;
}

int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len)
{
	return zstream_buf(out, in, in_len, GIT_ZSTREAM_DEFLATE);
}

int git_zstream_inflatebuf(git_buf *out, const void *in, size_t in_len)
{
	return zstream_buf(out, in, in_len, GIT_ZSTREAM_INFLATE);
}
