///////////////////////////////////////////////////////////////////////////////
//
/// \file       stream_encoder_single.c
/// \brief      Encodes Single-Block .lzma files
//
//  Copyright (C) 2007 Lasse Collin
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
///////////////////////////////////////////////////////////////////////////////

#include "stream_common.h"
#include "block_encoder.h"


struct lzma_coder_s {
	/// Uncompressed Size, Backward Size, and Footer Magic Bytes are
	/// part of Block in the file format specification, but it is simpler
	/// to implement them as part of Stream.
	enum {
		SEQ_HEADERS,
		SEQ_DATA,
		SEQ_FOOTER,
	} sequence;

	/// Block encoder
	lzma_next_coder block_encoder;

	/// Block encoder options
	lzma_options_block block_options;

	/// Stream Flags; we need to have these in this struct so that we
	/// can encode Stream Footer.
	lzma_stream_flags stream_flags;

	/// Stream Header + Block Header, or Stream Footer
	uint8_t *header;
	size_t header_pos;
	size_t header_size;
};


static lzma_ret
stream_encode(lzma_coder *coder, lzma_allocator *allocator,
		const uint8_t *restrict in, size_t *restrict in_pos,
		size_t in_size, uint8_t *restrict out, size_t *out_pos,
		size_t out_size, lzma_action action)
{
	// NOTE: We don't check if the amount of input is in the proper limits,
	// because the Block encoder will do it for us.

	while (*out_pos < out_size)
	switch (coder->sequence) {
	case SEQ_HEADERS:
		bufcpy(coder->header, &coder->header_pos, coder->header_size,
				out, out_pos, out_size);

		if (coder->header_pos == coder->header_size) {
			coder->header_pos = 0;
			coder->sequence = SEQ_DATA;
		}

		break;

	case SEQ_DATA: {
		const lzma_ret ret = coder->block_encoder.code(
				coder->block_encoder.coder, allocator,
				in, in_pos, in_size,
				out, out_pos, out_size, action);
		if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH)
			return ret;

		assert(*in_pos == in_size);

		assert(coder->header_size >= LZMA_STREAM_TAIL_SIZE);
		coder->header_size = LZMA_STREAM_TAIL_SIZE;

		return_if_error(lzma_stream_tail_encode(
				coder->header, &coder->stream_flags));

		coder->sequence = SEQ_FOOTER;
		break;
	}

	case SEQ_FOOTER:
		bufcpy(coder->header, &coder->header_pos, coder->header_size,
				out, out_pos, out_size);

		return coder->header_pos == coder->header_size
				? LZMA_STREAM_END : LZMA_OK;

	default:
		return LZMA_PROG_ERROR;
	}

	return LZMA_OK;
}


static void
stream_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
{
	lzma_next_coder_end(&coder->block_encoder, allocator);
	lzma_free(coder->header, allocator);
	lzma_free(coder, allocator);
	return;
}


static lzma_ret
stream_encoder_init(lzma_next_coder *next,
		lzma_allocator *allocator, const lzma_options_stream *options)
{
	if (options == NULL)
		return LZMA_PROG_ERROR;

	if (next->coder == NULL) {
		next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
		if (next->coder == NULL)
			return LZMA_MEM_ERROR;

		next->code = &stream_encode;
		next->end = &stream_encoder_end;
		next->coder->block_encoder = LZMA_NEXT_CODER_INIT;
	} else {
		// Free the previous buffer, if any.
		lzma_free(next->coder->header, allocator);
	}

	// At this point, next->coder->header points to nothing useful.
	next->coder->header = NULL;

	// Basic initializations
	next->coder->sequence = SEQ_HEADERS;
	next->coder->header_pos = 0;

	// Initialize next->coder->stream_flags.
	next->coder->stream_flags = (lzma_stream_flags){
		.check = options->check,
		.has_crc32 = options->has_crc32,
		.is_multi = false,
	};

	// Initialize next->coder->block_options.
	next->coder->block_options = (lzma_options_block){
		.check = options->check,
		.has_crc32 = options->has_crc32,
		.has_eopm = options->uncompressed_size
				== LZMA_VLI_VALUE_UNKNOWN,
		.is_metadata = false,
		.has_uncompressed_size_in_footer = options->uncompressed_size
				== LZMA_VLI_VALUE_UNKNOWN,
		.has_backward_size = true,
		.handle_padding = false,
		.compressed_size = LZMA_VLI_VALUE_UNKNOWN,
		.uncompressed_size = options->uncompressed_size,
		.compressed_reserve = 0,
		.uncompressed_reserve = 0,
		.total_size = LZMA_VLI_VALUE_UNKNOWN,
		.total_limit = LZMA_VLI_VALUE_UNKNOWN,
		.uncompressed_limit = LZMA_VLI_VALUE_UNKNOWN,
		.padding = LZMA_BLOCK_HEADER_PADDING_AUTO,
		.alignment = options->alignment + LZMA_STREAM_HEADER_SIZE,
	};
	memcpy(next->coder->block_options.filters, options->filters,
				sizeof(options->filters));

	return_if_error(lzma_block_header_size(&next->coder->block_options));

	// Encode Stream Flags and Block Header into next->coder->header.
	next->coder->header_size = (size_t)(LZMA_STREAM_HEADER_SIZE)
			+ next->coder->block_options.header_size;
	next->coder->header = lzma_alloc(next->coder->header_size, allocator);
	if (next->coder->header == NULL)
		return LZMA_MEM_ERROR;

	return_if_error(lzma_stream_header_encode(next->coder->header,
			&next->coder->stream_flags));

	return_if_error(lzma_block_header_encode(
			next->coder->header + LZMA_STREAM_HEADER_SIZE,
			&next->coder->block_options));

	// Initialize the Block encoder.
	return lzma_block_encoder_init(&next->coder->block_encoder, allocator,
			&next->coder->block_options);
}


/*
extern lzma_ret
lzma_stream_encoder_single_init(lzma_next_coder *next,
		lzma_allocator *allocator, const lzma_options_stream *options)
{
	lzma_next_coder_init(stream_encoder_init, allocator, options);
}
*/


extern LZMA_API lzma_ret
lzma_stream_encoder_single(
		lzma_stream *strm, const lzma_options_stream *options)
{
	lzma_next_strm_init(strm, stream_encoder_init, options);

	strm->internal->supported_actions[LZMA_RUN] = true;
	strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
	strm->internal->supported_actions[LZMA_FINISH] = true;

	return LZMA_OK;
}
