///////////////////////////////////////////////////////////////////////////////
//
/// \file       info.c
/// \brief      Collects and verifies integrity of Stream size information
//
//  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 "common.h"


struct lzma_info_s {
	struct {
		/// Known Size of Header Metadata Block; here's some
		/// special things:
		///  - LZMA_VLI_VALUE_UNKNOWN indicates that we don't know
		///    if Header Metadata Block is present.
		///  - 0 indicates that Header Metadata Block is not present.
		lzma_vli header_metadata_size;

		/// Known Total Size of the Data Blocks in the Stream
		lzma_vli total_size;

		/// Known Uncompressed Size of the Data Blocks in the Stream
		lzma_vli uncompressed_size;

		/// Known Size of Footer Metadata Block
		lzma_vli footer_metadata_size;
	} known;

	struct {
		/// Sum of Total Size fields stored to the Index so far
		lzma_vli total_size;

		/// Sum of Uncompressed Size fields stored to the Index so far
		lzma_vli uncompressed_size;

		/// First Index Record in the list, or NULL if Index is empty.
		lzma_index *head;

		/// Number of Index Records
		size_t record_count;

		/// Number of Index Records
		size_t incomplete_count;

		/// True when we know that no more Records will get added
		/// to the Index.
		bool is_final;
	} index;

	/// Start offset of the Stream. This is needed to calculate
	/// lzma_info_iter.stream_offset.
	lzma_vli stream_start_offset;

	/// True if Index is present in Header Metadata Block
	bool has_index_in_header_metadata;
};


//////////////////////
// Create/Reset/End //
//////////////////////

static void
index_init(lzma_info *info)
{
	info->index.total_size = 0;
	info->index.uncompressed_size = 0;
	info->index.head = NULL;
	info->index.record_count = 0;
	info->index.incomplete_count = 0;
	info->index.is_final = false;
	return;
}


static void
info_init(lzma_info *info)
{
	info->known.header_metadata_size = LZMA_VLI_VALUE_UNKNOWN;
	info->known.total_size = LZMA_VLI_VALUE_UNKNOWN;
	info->known.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN;
	info->known.footer_metadata_size = LZMA_VLI_VALUE_UNKNOWN;
	info->stream_start_offset = 0;
	info->has_index_in_header_metadata = false;

	index_init(info);

	return;
}


extern LZMA_API lzma_info *
lzma_info_init(lzma_info *info, lzma_allocator *allocator)
{
	if (info == NULL)
		info = lzma_alloc(sizeof(lzma_info), allocator);
	else
		lzma_index_free(info->index.head, allocator);

	if (info != NULL)
		info_init(info);

	return info;
}


extern LZMA_API void
lzma_info_free(lzma_info *info, lzma_allocator *allocator)
{
	lzma_index_free(info->index.head, allocator);
	lzma_free(info, allocator);
	return;
}


/////////
// Set //
/////////

static lzma_ret
set_size(lzma_vli new_size, lzma_vli *known_size, lzma_vli index_size,
		bool forbid_zero)
{
	assert(new_size <= LZMA_VLI_VALUE_MAX);

	lzma_ret ret = LZMA_OK;

	if (forbid_zero && new_size == 0)
		ret = LZMA_PROG_ERROR;
	else if (index_size > new_size)
		ret = LZMA_DATA_ERROR;
	else if (*known_size == LZMA_VLI_VALUE_UNKNOWN)
		*known_size = new_size;
	else if (*known_size != new_size)
		ret = LZMA_DATA_ERROR;

	return ret;
}


extern LZMA_API lzma_ret
lzma_info_size_set(lzma_info *info, lzma_info_size type, lzma_vli size)
{
	if (size > LZMA_VLI_VALUE_MAX)
		return LZMA_PROG_ERROR;

	switch (type) {
	case LZMA_INFO_STREAM_START:
		info->stream_start_offset = size;
		return LZMA_OK;

	case LZMA_INFO_HEADER_METADATA:
		return set_size(size, &info->known.header_metadata_size,
				0, false);

	case LZMA_INFO_TOTAL:
		return set_size(size, &info->known.total_size,
				info->index.total_size, true);

	case LZMA_INFO_UNCOMPRESSED:
		return set_size(size, &info->known.uncompressed_size,
				info->index.uncompressed_size, false);

	case LZMA_INFO_FOOTER_METADATA:
		return set_size(size, &info->known.footer_metadata_size,
				0, true);
	}

	return LZMA_PROG_ERROR;
}


extern LZMA_API lzma_ret
lzma_info_index_set(lzma_info *info, lzma_allocator *allocator,
		lzma_index *i_new, lzma_bool eat_index)
{
	if (i_new == NULL)
		return LZMA_PROG_ERROR;

	lzma_index *i_old = info->index.head;

	if (i_old != NULL) {
		while (true) {
			// If the new Index has fewer Records than the old one,
			// the new Index cannot be valid.
			if (i_new == NULL)
				return LZMA_DATA_ERROR;

			// The new Index must be complete i.e. no unknown
			// values.
			if (i_new->total_size > LZMA_VLI_VALUE_MAX
					|| i_new->uncompressed_size
						> LZMA_VLI_VALUE_MAX) {
				if (eat_index)
					lzma_index_free(i_new, allocator);

				return LZMA_PROG_ERROR;
			}

			// Compare the values from the new Index with the old
			// Index. The old Index may be incomplete; in that
			// case we
			//  - use the value from the new Index as is;
			//  - update the appropriate info->index.foo_size; and
			//  - decrease the count of incomplete Index Records.
			bool was_incomplete = false;

			if (i_old->total_size == LZMA_VLI_VALUE_UNKNOWN) {
				assert(!info->index.is_final);
				was_incomplete = true;

				i_old->total_size = i_new->total_size;

				if (lzma_vli_add(info->index.total_size,
						i_new->total_size)) {
					if (eat_index)
						lzma_index_free(i_new,
								allocator);

					return LZMA_PROG_ERROR;
				}
			} else if (i_old->total_size != i_new->total_size) {
				if (eat_index)
					lzma_index_free(i_new, allocator);

				return LZMA_DATA_ERROR;
			}

			if (i_old->uncompressed_size
					== LZMA_VLI_VALUE_UNKNOWN) {
				assert(!info->index.is_final);
				was_incomplete = true;

				i_old->uncompressed_size
						= i_new->uncompressed_size;

				if (lzma_vli_add(info->index.uncompressed_size,
						i_new->uncompressed_size)) {
					if (eat_index)
						lzma_index_free(i_new,
								allocator);

					return LZMA_PROG_ERROR;
				}
			} else if (i_old->uncompressed_size
					!= i_new->uncompressed_size) {
				if (eat_index)
					lzma_index_free(i_new, allocator);

				return LZMA_DATA_ERROR;
			}

			if (was_incomplete) {
				assert(!info->index.is_final);
				assert(info->index.incomplete_count > 0);
				--info->index.incomplete_count;
			}

			// Get rid of *i_new. It's now identical with *i_old.
			lzma_index *tmp = i_new->next;
			if (eat_index)
				lzma_free(i_new, allocator);

			i_new = tmp;

			// We want to leave i_old pointing to the last
			// Index Record in the old Index. This way we can
			// concatenate the possible new Records from i_new.
			if (i_old->next == NULL)
				break;

			i_old = i_old->next;
		}
	}

	assert(info->index.incomplete_count == 0);

	// If Index was already known to be final, i_new must be NULL now.
	// The new Index cannot contain more Records that we already have.
	if (info->index.is_final) {
		assert(info->index.head != NULL);

		if (i_new != NULL) {
			if (eat_index)
				lzma_index_free(i_new, allocator);

			return LZMA_DATA_ERROR;
		}

		return LZMA_OK;
	}

	// The rest of the new Index is merged to the old Index. Keep the
	// current i_new pointer in available. We need it when merging the
	// new Index with the old one, and if an error occurs so we can
	// get rid of the broken part of the new Index.
	lzma_index *i_start = i_new;
	while (i_new != NULL) {
		// The new Index must be complete i.e. no unknown values.
		if (i_new->total_size > LZMA_VLI_VALUE_MAX
				|| i_new->uncompressed_size
					> LZMA_VLI_VALUE_MAX) {
			if (eat_index)
				lzma_index_free(i_start, allocator);

			return LZMA_PROG_ERROR;
		}

		// Update info->index.foo_sizes.
		if (lzma_vli_add(info->index.total_size, i_new->total_size)
				|| lzma_vli_add(info->index.uncompressed_size,
					i_new->uncompressed_size)) {
			if (eat_index)
				lzma_index_free(i_start, allocator);

			return LZMA_PROG_ERROR;
		}

		++info->index.record_count;
		i_new = i_new->next;
	}

	// All the Records in the new Index are good, and info->index.foo_sizes
	// were successfully updated.
	if (lzma_info_index_finish(info) != LZMA_OK) {
		if (eat_index)
			lzma_index_free(i_start, allocator);

		return LZMA_DATA_ERROR;
	}

	// The Index is ready to be merged. If we aren't supposed to eat
	// the Index, make a copy of it first.
	if (!eat_index && i_start != NULL) {
		i_start = lzma_index_dup(i_start, allocator);
		if (i_start == NULL)
			return LZMA_MEM_ERROR;
	}

	// Concatenate the new Index with the old one. Note that it is
	// possible that we don't have any old Index.
	if (info->index.head == NULL)
		info->index.head = i_start;
	else
		i_old->next = i_start;

	return LZMA_OK;
}


extern LZMA_API lzma_ret
lzma_info_metadata_set(lzma_info *info, lzma_allocator *allocator,
		lzma_metadata *metadata, lzma_bool is_header_metadata,
		lzma_bool eat_index)
{
	// Validate *metadata.
	if (metadata->header_metadata_size > LZMA_VLI_VALUE_MAX
			|| !lzma_vli_is_valid(metadata->total_size)
			|| !lzma_vli_is_valid(metadata->uncompressed_size)) {
		if (eat_index) {
			lzma_index_free(metadata->index, allocator);
			metadata->index = NULL;
		}

		return LZMA_PROG_ERROR;
	}

	// Index
	if (metadata->index != NULL) {
		if (is_header_metadata)
			info->has_index_in_header_metadata = true;

		const lzma_ret ret = lzma_info_index_set(
				info, allocator, metadata->index, eat_index);

		if (eat_index)
			metadata->index = NULL;

		if (ret != LZMA_OK)
			return ret;

	} else if (!is_header_metadata
			&& (metadata->total_size == LZMA_VLI_VALUE_UNKNOWN
				|| !info->has_index_in_header_metadata)) {
		// Either Total Size or Index must be present in Footer
		// Metadata Block. If Index is not present, it must have
		// already been in the Header Metadata Block. Since we
		// got here, these conditions weren't met.
		return LZMA_DATA_ERROR;
	}

	// Size of Header Metadata
	if (!is_header_metadata)
		return_if_error(lzma_info_size_set(
				info, LZMA_INFO_HEADER_METADATA,
				metadata->header_metadata_size));

	// Total Size
	if (metadata->total_size != LZMA_VLI_VALUE_UNKNOWN)
		return_if_error(lzma_info_size_set(info,
				LZMA_INFO_TOTAL, metadata->total_size));

	// Uncompressed Size
	if (metadata->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
		return_if_error(lzma_info_size_set(info,
				LZMA_INFO_UNCOMPRESSED,
				metadata->uncompressed_size));

	return LZMA_OK;
}


/////////
// Get //
/////////

extern LZMA_API lzma_vli
lzma_info_size_get(const lzma_info *info, lzma_info_size type)
{
	switch (type) {
	case LZMA_INFO_STREAM_START:
		return info->stream_start_offset;

	case LZMA_INFO_HEADER_METADATA:
		return info->known.header_metadata_size;

	case LZMA_INFO_TOTAL:
		return info->known.total_size;

	case LZMA_INFO_UNCOMPRESSED:
		return info->known.uncompressed_size;

	case LZMA_INFO_FOOTER_METADATA:
		return info->known.footer_metadata_size;
	}

	return LZMA_VLI_VALUE_UNKNOWN;
}


extern LZMA_API lzma_index *
lzma_info_index_get(lzma_info *info, lzma_bool detach)
{
	lzma_index *i = info->index.head;

	if (detach)
		index_init(info);

	return i;
}


extern LZMA_API size_t
lzma_info_index_count_get(const lzma_info *info)
{
	return info->index.record_count;
}


/////////////////
// Incremental //
/////////////////

enum {
	ITER_INFO,
	ITER_INDEX,
	ITER_RESERVED_1,
	ITER_RESERVED_2,
};


#define iter_info ((lzma_info *)(iter->internal[ITER_INFO]))

#define iter_index ((lzma_index *)(iter->internal[ITER_INDEX]))


extern LZMA_API void
lzma_info_iter_begin(lzma_info *info, lzma_info_iter *iter)
{
	*iter = (lzma_info_iter){
		.total_size = LZMA_VLI_VALUE_UNKNOWN,
		.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
		.stream_offset = LZMA_VLI_VALUE_UNKNOWN,
		.uncompressed_offset = LZMA_VLI_VALUE_UNKNOWN,
		.internal = { info, NULL, NULL, NULL },
	};

	return;
}


extern LZMA_API lzma_ret
lzma_info_iter_next(lzma_info_iter *iter, lzma_allocator *allocator)
{
	// FIXME debug remove
	lzma_info *info = iter_info;
	(void)info;

	if (iter_index == NULL) {
		// The first call after lzma_info_iter_begin().
		if (iter_info->known.header_metadata_size
				== LZMA_VLI_VALUE_UNKNOWN)
			iter->stream_offset = LZMA_VLI_VALUE_UNKNOWN;
		else if (lzma_vli_sum3(iter->stream_offset,
				iter_info->stream_start_offset,
				LZMA_STREAM_HEADER_SIZE,
				iter_info->known.header_metadata_size))
			return LZMA_PROG_ERROR;

		iter->uncompressed_offset = 0;

		if (iter_info->index.head != NULL) {
			// The first Index Record has already been allocated.
			iter->internal[ITER_INDEX] = iter_info->index.head;
			iter->total_size = iter_index->total_size;
			iter->uncompressed_size
					= iter_index->uncompressed_size;
			return LZMA_OK;
		}
	} else {
		// Update iter->*_offsets.
		if (iter->stream_offset != LZMA_VLI_VALUE_UNKNOWN) {
			if (iter_index->total_size == LZMA_VLI_VALUE_UNKNOWN)
				iter->stream_offset = LZMA_VLI_VALUE_UNKNOWN;
			else if (lzma_vli_add(iter->stream_offset,
					iter_index->total_size))
				return LZMA_DATA_ERROR;
		}

		if (iter->uncompressed_offset != LZMA_VLI_VALUE_UNKNOWN) {
			if (iter_index->uncompressed_size
					== LZMA_VLI_VALUE_UNKNOWN)
				iter->uncompressed_offset
						= LZMA_VLI_VALUE_UNKNOWN;
			else if (lzma_vli_add(iter->uncompressed_offset,
					iter_index->uncompressed_size))
				return LZMA_DATA_ERROR;
		}

		if (iter_index->next != NULL) {
			// The next Record has already been allocated.
			iter->internal[ITER_INDEX] = iter_index->next;
			iter->total_size = iter_index->total_size;
			iter->uncompressed_size
					= iter_index->uncompressed_size;
			return LZMA_OK;
		}
	}

	// Don't add new Records to a final Index.
	if (iter_info->index.is_final)
		return LZMA_DATA_ERROR;

	// Allocate and initialize a new Index Record.
	lzma_index *i = lzma_alloc(sizeof(lzma_index), allocator);
	if (i == NULL)
		return LZMA_MEM_ERROR;

	i->total_size = LZMA_VLI_VALUE_UNKNOWN;
	i->uncompressed_size = LZMA_VLI_VALUE_UNKNOWN;
	i->next = NULL;

	iter->total_size = LZMA_VLI_VALUE_UNKNOWN;
	iter->uncompressed_size = LZMA_VLI_VALUE_UNKNOWN;

	// Decide where to put the new Index Record.
	if (iter_info->index.head == NULL)
		iter_info->index.head = i;

	if (iter_index != NULL)
		iter_index->next = i;

	iter->internal[ITER_INDEX] = i;

	++iter_info->index.record_count;
	++iter_info->index.incomplete_count;

	return LZMA_OK;
}


extern LZMA_API lzma_ret
lzma_info_iter_set(lzma_info_iter *iter,
		lzma_vli total_size, lzma_vli uncompressed_size)
{
	// FIXME debug remove
	lzma_info *info = iter_info;
	(void)info;

	if (iter_index == NULL || !lzma_vli_is_valid(total_size)
			|| !lzma_vli_is_valid(uncompressed_size))
		return LZMA_PROG_ERROR;

	const bool was_incomplete = iter_index->total_size
				== LZMA_VLI_VALUE_UNKNOWN
			|| iter_index->uncompressed_size
				== LZMA_VLI_VALUE_UNKNOWN;

	if (total_size != LZMA_VLI_VALUE_UNKNOWN) {
		if (iter_index->total_size == LZMA_VLI_VALUE_UNKNOWN) {
			iter_index->total_size = total_size;

			if (lzma_vli_add(iter_info->index.total_size,
						total_size)
					|| iter_info->index.total_size
						> iter_info->known.total_size)
				return LZMA_DATA_ERROR;

		} else if (iter_index->total_size != total_size) {
			return LZMA_DATA_ERROR;
		}
	}

	if (uncompressed_size != LZMA_VLI_VALUE_UNKNOWN) {
		if (iter_index->uncompressed_size == LZMA_VLI_VALUE_UNKNOWN) {
			iter_index->uncompressed_size = uncompressed_size;

			if (lzma_vli_add(iter_info->index.uncompressed_size,
						uncompressed_size)
					|| iter_info->index.uncompressed_size
					> iter_info->known.uncompressed_size)
				return LZMA_DATA_ERROR;

		} else if (iter_index->uncompressed_size
				!= uncompressed_size) {
			return LZMA_DATA_ERROR;
		}
	}

	// Check if the new information we got managed to finish this
	// Index Record. If so, update the count of incomplete Index Records.
	if (was_incomplete && iter_index->total_size
				!= LZMA_VLI_VALUE_UNKNOWN
			&& iter_index->uncompressed_size
				!= LZMA_VLI_VALUE_UNKNOWN) {
		assert(iter_info->index.incomplete_count > 0);
		--iter_info->index.incomplete_count;
	}

	// Make sure that the known sizes are now available in *iter.
	iter->total_size = iter_index->total_size;
	iter->uncompressed_size = iter_index->uncompressed_size;

	return LZMA_OK;
}


extern LZMA_API lzma_ret
lzma_info_index_finish(lzma_info *info)
{
	if (info->index.record_count == 0 || info->index.incomplete_count > 0
			|| lzma_info_size_set(info, LZMA_INFO_TOTAL,
				info->index.total_size)
			|| lzma_info_size_set(info, LZMA_INFO_UNCOMPRESSED,
				info->index.uncompressed_size))
		return LZMA_DATA_ERROR;

	info->index.is_final = true;

	return LZMA_OK;
}


//////////////
// Locating //
//////////////

extern LZMA_API lzma_vli
lzma_info_metadata_locate(const lzma_info *info, lzma_bool is_header_metadata)
{
	bool error = false;
	lzma_vli size = 0;

	if (info->known.header_metadata_size == LZMA_VLI_VALUE_UNKNOWN) {
		// We don't know if Header Metadata Block is present, thus
		// we cannot locate it either.
		//
		// Well, you could say that just assume that it is present.
		// I'm not sure if this is useful. But it can be useful to
		// be able to use this function and get LZMA_VLI_VALUE_UNKNOWN
		// to detect that Header Metadata Block wasn't present.
		error = true;
	} else if (is_header_metadata) {
		error = lzma_vli_sum(size, info->stream_start_offset,
				LZMA_STREAM_HEADER_SIZE);
	} else if (!info->index.is_final) {
		// Since we don't know if we have all the Index Records yet,
		// we cannot know where the Footer Metadata Block is.
		error = true;
	} else {
		error = lzma_vli_sum4(size, info->stream_start_offset,
				LZMA_STREAM_HEADER_SIZE,
				info->known.header_metadata_size,
				info->known.total_size);
	}

	return error ? LZMA_VLI_VALUE_UNKNOWN : size;
}


extern LZMA_API uint32_t
lzma_info_metadata_alignment_get(
		const lzma_info *info, lzma_bool is_header_metadata)
{
	uint32_t alignment;

	if (is_header_metadata) {
		alignment = info->stream_start_offset
				+ LZMA_STREAM_HEADER_SIZE;
	} else {
		alignment = info->stream_start_offset + LZMA_STREAM_HEADER_SIZE
				+ info->known.header_metadata_size
				+ info->known.total_size;
	}

	return alignment;
}


extern LZMA_API lzma_ret
lzma_info_iter_locate(lzma_info_iter *iter, lzma_allocator *allocator,
		lzma_vli uncompressed_offset, lzma_bool allow_alloc)
{
	if (iter == NULL || uncompressed_offset > LZMA_VLI_VALUE_MAX)
		return LZMA_PROG_ERROR;

	// Quick check in case Index is final.
	if (iter_info->index.is_final) {
		assert(iter_info->known.uncompressed_size
				== iter_info->index.uncompressed_size);
		if (uncompressed_offset >= iter_info->index.uncompressed_size)
			return LZMA_DATA_ERROR;
	}

	// TODO: Optimize so that it uses existing info from *iter when
	// seeking forward.

	// Initialize *iter
	if (iter_info->known.header_metadata_size != LZMA_VLI_VALUE_UNKNOWN) {
		if (lzma_vli_sum3(iter->stream_offset,
				iter_info->stream_start_offset,
				LZMA_STREAM_HEADER_SIZE,
				iter_info->known.header_metadata_size))
			return LZMA_PROG_ERROR;
	} else {
		// We don't know the Size of Header Metadata Block, thus
		// we cannot calculate the Stream offset either.
		iter->stream_offset = LZMA_VLI_VALUE_UNKNOWN;
	}

	iter->uncompressed_offset = 0;

	// If we have no Index Records, it's obvious that we need to
	// add a new one.
	if (iter_info->index.head == NULL) {
		assert(!iter_info->index.is_final);
		if (!allow_alloc)
			return LZMA_DATA_ERROR;

		return lzma_info_iter_next(iter, allocator);
	}

	// Locate an appropriate Index Record.
	lzma_index *i = iter_info->index.head;
	while (true) {
		// - If Uncompressed Size in the Record is unknown,
		//   we have no chance to search further.
		// - If the next Record would go past the requested offset,
		//   we have found our target Data Block.
		if (i->uncompressed_size == LZMA_VLI_VALUE_UNKNOWN
				|| iter->uncompressed_offset
				+ i->uncompressed_size > uncompressed_offset) {
			iter->total_size = i->total_size;
			iter->uncompressed_size = i->uncompressed_size;
			iter->internal[ITER_INDEX] = i;
			return LZMA_OK;
		}

		// Update the stream offset. It may be unknown if we didn't
		// know the size of Header Metadata Block.
		if (iter->stream_offset != LZMA_VLI_VALUE_UNKNOWN)
			if (lzma_vli_add(iter->stream_offset, i->total_size))
				return LZMA_PROG_ERROR;

		// Update the uncompressed offset. This cannot overflow since
		// the Index is known to be valid.
		iter->uncompressed_offset += i->uncompressed_size;

		// Move to the next Block.
		if (i->next == NULL) {
			assert(!iter_info->index.is_final);
			if (!allow_alloc)
				return LZMA_DATA_ERROR;

			iter->internal[ITER_INDEX] = i;
			return lzma_info_iter_next(iter, allocator);
		}

		i = i->next;
	}
}
