/*
    libparted
    Copyright (C) 1998, 1999, 2000, 2001, 2007 Free Software Foundation, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

#include <config.h>
#include <string.h>

#include "fat.h"

#ifndef DISCOVER_ONLY

static int
needs_duplicating (const FatOpContext* ctx, FatFragment frag)
{
	FatSpecific*	old_fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatCluster	cluster = fat_frag_to_cluster (ctx->old_fs, frag);
	FatClusterFlag	flag;

	PED_ASSERT (cluster >= 2 && cluster < old_fs_info->cluster_count + 2,
		    return 0);

	flag = fat_get_fragment_flag (ctx->old_fs, frag);
	switch (flag) {
	case FAT_FLAG_FREE:
		return 0;

	case FAT_FLAG_DIRECTORY:
		return 1;

	case FAT_FLAG_FILE:
		return fat_op_context_map_static_fragment (ctx, frag) == -1;
	
	case FAT_FLAG_BAD:
		return 0;
	}

	return 0;
}

static int
search_next_fragment (FatOpContext* ctx)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (ctx->old_fs);

	for (; ctx->buffer_offset < fs_info->frag_count; ctx->buffer_offset++) {
		if (needs_duplicating (ctx, ctx->buffer_offset))
			return 1;
	}
	return 0;	/* all done! */
}

static int
read_marked_fragments (FatOpContext* ctx, FatFragment length)
{
	FatSpecific*		fs_info = FAT_SPECIFIC (ctx->old_fs);
	int			status;
	FatFragment		i;

	ped_exception_fetch_all ();
	status = fat_read_fragments (ctx->old_fs, fs_info->buffer,
				     ctx->buffer_offset, length);
	ped_exception_leave_all ();
	if (status)
		return 1;

	ped_exception_catch ();

/* something bad happened, so read fragments one by one.  (The error may
   have occurred on an unused fragment: who cares) */
	for (i = 0; i < length; i++) {
		if (ctx->buffer_map [i]) {
			if (!fat_read_fragment (ctx->old_fs,
			      fs_info->buffer + i * fs_info->frag_size,
			      ctx->buffer_offset + i))
				return 0;
		}
	}

	return 1;
}

static int
fetch_fragments (FatOpContext* ctx)
{
	FatSpecific*	old_fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatFragment	fetch_length = 0;
	FatFragment	frag;

	for (frag = 0; frag < ctx->buffer_frags; frag++)
		ctx->buffer_map [frag] = -1;

	for (frag = 0;
	     frag < ctx->buffer_frags
		&& ctx->buffer_offset + frag < old_fs_info->frag_count;
	     frag++) {
		if (needs_duplicating (ctx, ctx->buffer_offset + frag)) {
			ctx->buffer_map [frag] = 1;
			fetch_length = frag + 1;
		}
	}

	if (!read_marked_fragments (ctx, fetch_length))
		return 0;

	return 1;
}

/*****************************************************************************
 * here starts the write code.  All assumes that ctx->buffer_map [first] and
 * ctx->buffer_map [last] are occupied by fragments that need to be duplicated.
 *****************************************************************************/

/* finds the first fragment that is not going to get overwritten (that needs to
   get read in) */
static FatFragment
get_first_underlay (const FatOpContext* ctx, int first, int last)
{
	int		old;
	FatFragment	new;

	PED_ASSERT (first <= last, return 0);

	new = ctx->buffer_map [first];
	for (old = first + 1; old <= last; old++) {
		if (ctx->buffer_map [old] == -1)
			continue;
		new++;
		if (ctx->buffer_map [old] != new)
			return new;
	}
	return -1;
}

/* finds the last fragment that is not going to get overwritten (that needs to
   get read in) */
static FatFragment
get_last_underlay (const FatOpContext* ctx, int first, int last)
{
	int		old;
	FatFragment	new;

	PED_ASSERT (first <= last, return 0);

	new = ctx->buffer_map [last];
	for (old = last - 1; old >= first; old--) {
		if (ctx->buffer_map [old] == -1)
			continue;
		new--;
		if (ctx->buffer_map [old] != new)
			return new;
	}
	return -1;
}

/* "underlay" refers to the "static" fragments, that remain unchanged.
 * when writing large chunks at a time, we don't want to clobber these,
 * so we read them in, and write them back again.  MUCH quicker that way.
 */
static int
quick_group_write_read_underlay (FatOpContext* ctx, int first, int last)
{
	FatSpecific*	new_fs_info = FAT_SPECIFIC (ctx->new_fs);
	FatFragment	first_underlay;
	FatFragment	last_underlay;
	FatFragment	underlay_length;

	PED_ASSERT (first <= last, return 0);

	first_underlay = get_first_underlay (ctx, first, last);
	if (first_underlay == -1)
		return 1;
	last_underlay = get_last_underlay (ctx, first, last);

	PED_ASSERT (first_underlay <= last_underlay, return 0);

	underlay_length = last_underlay - first_underlay + 1;
	if (!fat_read_fragments (ctx->new_fs,
				new_fs_info->buffer 
				   + (first_underlay - ctx->buffer_map [first])
					* new_fs_info->frag_size,
				first_underlay,
				underlay_length))
		return 0;
	return 1;
}

/* quick_group_write() makes no attempt to recover from errors - just
 * does things fast.  If there is an error, slow_group_write() is
 * called.
 *    Note: we do syncing writes, to make sure there isn't any
 * error writing out.  It's rather difficult recovering from errors
 * further on.
 */
static int
quick_group_write (FatOpContext* ctx, int first, int last)
{
	FatSpecific*		old_fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatSpecific*		new_fs_info = FAT_SPECIFIC (ctx->new_fs);
	int			active_length;
	int			i;
	int			offset;

	PED_ASSERT (first <= last, return 0);

	ped_exception_fetch_all ();
	if (!quick_group_write_read_underlay (ctx, first, last))
		goto error;

	for (i = first; i <= last; i++) {
		if (ctx->buffer_map [i] == -1)
			continue;

		offset = ctx->buffer_map [i] - ctx->buffer_map [first];
		memcpy (new_fs_info->buffer + offset * new_fs_info->frag_size,
			old_fs_info->buffer + i * new_fs_info->frag_size,
			new_fs_info->frag_size);
	}

	active_length = ctx->buffer_map [last] - ctx->buffer_map [first] + 1;
	if (!fat_write_sync_fragments (ctx->new_fs, new_fs_info->buffer,
				       ctx->buffer_map [first], active_length))
		goto error;

	ped_exception_leave_all ();
	return 1;

error:
	ped_exception_catch ();
	ped_exception_leave_all ();
	return 0;
}

/* Writes fragments out, one at a time, avoiding errors on redundant writes
 * on damaged parts of the disk we already know about.  If there's an error
 * on one of the required fragments, it gets marked as bad, and a replacement
 * is found.
 */
static int
slow_group_write (FatOpContext* ctx, int first, int last)
{
	FatSpecific*		old_fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatSpecific*		new_fs_info = FAT_SPECIFIC (ctx->new_fs);
	int			i;

	PED_ASSERT (first <= last, return 0);

	for (i = first; i <= last; i++) {
		if (ctx->buffer_map [i] == -1)
			continue;

		while (!fat_write_sync_fragment (ctx->new_fs,
			      old_fs_info->buffer + i * old_fs_info->frag_size,
			      ctx->buffer_map [i])) {
			fat_table_set_bad (new_fs_info->fat,
					   ctx->buffer_map [i]);
			ctx->buffer_map [i] = fat_table_alloc_cluster
						(new_fs_info->fat);
			if (ctx->buffer_map [i] == 0)
				return 0;
		}
	}
	return 1;
}

static int
update_remap (FatOpContext* ctx, int first, int last)
{
	int		i;

	PED_ASSERT (first <= last, return 0);

	for (i = first; i <= last; i++) {
		if (ctx->buffer_map [i] == -1)
			continue;
		ctx->remap [ctx->buffer_offset + i] = ctx->buffer_map [i];
	}

	return 1;
}

static int
group_write (FatOpContext* ctx, int first, int last)
{
	PED_ASSERT (first <= last, return 0);

	if (!quick_group_write (ctx, first, last)) {
		if (!slow_group_write (ctx, first, last))
			return 0;
	}
	if (!update_remap (ctx, first, last))
		return 0;
	return 1;
}

/* assumes fragment size and new_fs's cluster size are equal */
static int
write_fragments (FatOpContext* ctx)
{
	FatSpecific*		old_fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatSpecific*		new_fs_info = FAT_SPECIFIC (ctx->new_fs);
	int			group_start;
	int			group_end = -1;	/* shut gcc up! */
	FatFragment		mapped_length;
	FatFragment		i;
	FatCluster		new_cluster;

	PED_ASSERT (ctx->buffer_offset < old_fs_info->frag_count, return 0);

	group_start = -1;
	for (i = 0; i < ctx->buffer_frags; i++) {
		if (ctx->buffer_map [i] == -1)
			continue;

		ctx->frags_duped++;

		new_cluster = fat_table_alloc_cluster (new_fs_info->fat);
		if (!new_cluster)
			return 0;
		fat_table_set_eof (new_fs_info->fat, new_cluster);
		ctx->buffer_map [i] = fat_cluster_to_frag (ctx->new_fs,
							   new_cluster);

		if (group_start == -1)
			group_start = group_end = i;

		PED_ASSERT (ctx->buffer_map [i]
				>= ctx->buffer_map [group_start],
			    return 0);

		mapped_length = ctx->buffer_map [i]
				- ctx->buffer_map [group_start] + 1;
		if (mapped_length <= ctx->buffer_frags) {
			group_end = i;
		} else {
			/* ran out of room in the buffer, so write this group,
			 * and start a new one...
			 */
			if (!group_write (ctx, group_start, group_end))
				return 0;
			group_start = group_end = i;
		}
	}

	PED_ASSERT (group_start != -1, return 0);

	if (!group_write (ctx, group_start, group_end))
		return 0;
	return 1;
}

/*  default all fragments to unmoved
 */
static void
init_remap (FatOpContext* ctx)
{
	FatSpecific*		old_fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatFragment		i;

	for (i = 0; i < old_fs_info->frag_count; i++)
		ctx->remap[i] = fat_op_context_map_static_fragment (ctx, i);
}

static FatFragment
count_frags_to_dup (FatOpContext* ctx)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (ctx->old_fs);
	FatFragment	i;
	FatFragment	total;

	total = 0;

	for (i = 0; i < fs_info->frag_count; i++) {
		if (needs_duplicating (ctx, i))
			total++;
	}

	return total;
}

/*  duplicates unreachable file clusters, and all directory clusters
 */
int
fat_duplicate_clusters (FatOpContext* ctx, PedTimer* timer)
{
	FatFragment	total_frags_to_dup;

	init_remap (ctx);
	total_frags_to_dup = count_frags_to_dup (ctx);

	ped_timer_reset (timer);
	ped_timer_set_state_name (timer, "moving data");

	ctx->buffer_offset = 0;
	ctx->frags_duped = 0;
	while (search_next_fragment (ctx)) {
		ped_timer_update (
			timer, 1.0 * ctx->frags_duped / total_frags_to_dup);

		if (!fetch_fragments (ctx))
			return 0;
		if (!write_fragments (ctx))
			return 0;
		ctx->buffer_offset += ctx->buffer_frags;
	}

	ped_timer_update (timer, 1.0);
	return 1;
}

#endif /* !DISCOVER_ONLY */
