/*
    libparted - a library for manipulating disk partitions
    Copyright (C) 2004, 2005, 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
*/

#ifndef DISCOVER_ONLY

#include <config.h>

#include <parted/parted.h>
#include <parted/endian.h>
#include <parted/debug.h>
#include <stdint.h>

#if ENABLE_NLS
#  include <libintl.h>
#  define _(String) dgettext (PACKAGE, String)
#else
#  define _(String) (String)
#endif /* ENABLE_NLS */

#include "hfs.h"
#include "file.h"
#include "advfs.h"
#include "cache.h"

#include "reloc.h"

/* This function moves data of size blocks starting
   at block *ptr_fblock to block *ptr_to_fblock */
/* return new start or -1 on failure */
static int
hfs_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
			unsigned int *ptr_to_fblock, unsigned int size)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	unsigned int		i, ok = 0;
	unsigned int		next_to_fblock;
	unsigned int		start, stop;

	PED_ASSERT (hfs_block != NULL, return -1);
	PED_ASSERT (*ptr_to_fblock <= *ptr_fblock, return -1);
	/* quiet gcc */
	next_to_fblock = start = stop = 0;

/*
	Try to fit the extent AT or _BEFORE_ the wanted place,
	or then in the gap between dest and source.
	If failed try to fit the extent after source, for 2 pass relocation
	The extent is always copied in a non overlapping way
*/

	/* Backward search */
	/* 1 pass relocation AT or BEFORE *ptr_to_fblock */
	if (*ptr_to_fblock != *ptr_fblock) {
		start = stop = *ptr_fblock < *ptr_to_fblock+size ?
			       *ptr_fblock : *ptr_to_fblock+size;
		while (start && stop-start != size) {
			--start;
			if (TST_BLOC_OCCUPATION(priv_data->alloc_map,start))
				stop = start;
		}
		ok = (stop-start == size);
	}
	
	/* Forward search */
	/* 1 pass relocation in the gap merged with 2 pass reloc after source */
	if (!ok && *ptr_to_fblock != *ptr_fblock) {
		start = stop = *ptr_to_fblock+1;
		while (stop < PED_BE16_TO_CPU(priv_data->mdb->total_blocks)
		       && stop-start != size) {
			if (TST_BLOC_OCCUPATION(priv_data->alloc_map,stop))
				start = stop + 1;
			++stop;
		}
		ok = (stop-start == size);
	}

	/* new non overlapping room has been found ? */
	if (ok) {
		/* enough room */
		unsigned int j;
		unsigned int start_block =
			PED_BE16_TO_CPU (priv_data->mdb->start_block );
		unsigned int block_sz = 
			(PED_BE32_TO_CPU (priv_data->mdb->block_size)
			 / PED_SECTOR_SIZE_DEFAULT);

		if (stop > *ptr_to_fblock && stop <= *ptr_fblock)
			/* Fit in the gap */
			next_to_fblock = stop;
		else
			/* Before or after the gap */
			next_to_fblock = *ptr_to_fblock;

		/* move blocks */
		for (i = 0; i < size; /*i+=j*/) {
			PedSector 	abs_sector;
			unsigned int	ai;

			j = size - i; j = (j < hfs_block_count) ?
					   j : hfs_block_count ;

			abs_sector = start_block
				     + (PedSector) (*ptr_fblock + i) * block_sz;
			if (!ped_geometry_read (fs->geom, hfs_block, abs_sector,
						block_sz * j))
				return -1;

			abs_sector = start_block
				     + (PedSector) (start + i) * block_sz;
			if (!ped_geometry_write (fs->geom,hfs_block,abs_sector,
						 block_sz * j))
				return -1;

			for (ai = i+j; i < ai; i++) {
				/* free source block */
				CLR_BLOC_OCCUPATION(priv_data->alloc_map,
						    *ptr_fblock + i);

				/* set dest block */
				SET_BLOC_OCCUPATION(priv_data->alloc_map,
						    start + i);
			}
		}
		if (!ped_geometry_sync_fast (fs->geom))
			return -1;

		*ptr_fblock += size;
		*ptr_to_fblock = next_to_fblock;
	} else {
		if (*ptr_fblock != *ptr_to_fblock)
			/* not enough room, but try to continue */
			ped_exception_throw (PED_EXCEPTION_WARNING,
					PED_EXCEPTION_IGNORE,
					_("An extent has not been relocated."));
		start = *ptr_fblock;
		*ptr_fblock = *ptr_to_fblock = start + size;
	}

	return start;
}

/* Update MDB */
/* Return 0 if an error occurred */
/* Return 1 if everything ok */
int
hfs_update_mdb (PedFileSystem *fs)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	uint8_t			node[PED_SECTOR_SIZE_DEFAULT];

    	if (!ped_geometry_read (fs->geom, node, 2, 1))
		return 0;
	memcpy (node, priv_data->mdb, sizeof (HfsMasterDirectoryBlock));
	if (   !ped_geometry_write (fs->geom, node, 2, 1)
	    || !ped_geometry_write (fs->geom, node, fs->geom->length - 2, 1)
	    || !ped_geometry_sync_fast (fs->geom))
		return 0;
	return 1;
}

/* Generic relocator */
/* replace previous hfs_do_move_* */
static int
hfs_do_move (PedFileSystem* fs, unsigned int *ptr_src,
	     unsigned int *ptr_dest, HfsCPrivateCache* cache,
	     HfsCPrivateExtent* ref)
{
	uint8_t			node[PED_SECTOR_SIZE_DEFAULT];
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	HfsPrivateFile*		file;
	HfsExtDescriptor*	extent;
	HfsCPrivateExtent*	move;
	int			new_start;

	new_start = hfs_effect_move_extent (fs, ptr_src, ptr_dest, 
					    ref->ext_length);
	if (new_start == -1) return -1;

	if (ref->ext_start != (unsigned) new_start) {
		/* Load, modify & save */
		switch (ref->where) {
		/******** MDB *********/
		    case CR_PRIM_CAT :
			priv_data->catalog_file
			->first[ref->ref_index].start_block = 
				PED_CPU_TO_BE16(new_start);
			goto CR_PRIM;
		    case CR_PRIM_EXT :
			priv_data->extent_file
			->first[ref->ref_index].start_block = 
				PED_CPU_TO_BE16(new_start);		    
		    CR_PRIM :
			extent = ( HfsExtDescriptor* )
				 ( (uint8_t*)priv_data->mdb + ref->ref_offset );
			extent[ref->ref_index].start_block =
				PED_CPU_TO_BE16(new_start);
			if (!hfs_update_mdb(fs)) return -1;
			break;

		/********* BTREE *******/
		    case CR_BTREE_EXT_CAT :
			if (priv_data->catalog_file
			    ->cache[ref->ref_index].start_block
			    == PED_CPU_TO_BE16(ref->ext_start))
				priv_data->catalog_file
				->cache[ref->ref_index].start_block =
				PED_CPU_TO_BE16(new_start);
		    case CR_BTREE_EXT_0 :
			file = priv_data->extent_file;
			goto CR_BTREE;
		    case CR_BTREE_CAT :
			file = priv_data->catalog_file;
		    CR_BTREE:
			PED_ASSERT(ref->sect_by_block == 1
			           && ref->ref_offset < PED_SECTOR_SIZE_DEFAULT,
				   return -1);
			if (!hfs_file_read_sector(file, node, ref->ref_block))
				return -1;
			extent = ( HfsExtDescriptor* ) (node + ref->ref_offset);
			extent[ref->ref_index].start_block =
				PED_CPU_TO_BE16(new_start);
			if (!hfs_file_write_sector(file, node, ref->ref_block)
			    || !ped_geometry_sync_fast (fs->geom))
				return -1;
			break;

		/********** BUG ********/
		    default :
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("A reference to an extent comes from a place "
				  "it should not.  You should check the file "
				  "system!"));
			return -1;
			break;
		}

		/* Update the cache */
		move = hfsc_cache_move_extent(cache, ref->ext_start, new_start);
		if (!move) return -1; /* "cleanly" fail */
		PED_ASSERT(move == ref, return -1); /* generate a bug */
	}

	return new_start;
}

/* 0 error, 1 ok */
static int
hfs_save_allocation(PedFileSystem* fs)
{
	HfsPrivateFSData*	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	unsigned int		map_sectors;

	map_sectors = ( PED_BE16_TO_CPU (priv_data->mdb->total_blocks)
			+ PED_SECTOR_SIZE_DEFAULT * 8 - 1 )
		      / (PED_SECTOR_SIZE_DEFAULT * 8);
	return ( ped_geometry_write (fs->geom, priv_data->alloc_map,
			PED_BE16_TO_CPU (priv_data->mdb->volume_bitmap_block),
			map_sectors) );
}

/* This function moves an extent starting at block fblock to block to_fblock
   if there's enough room */
/* Return 1 if everything was fine */
/* Return -1 if an error occurred */
/* Return 0 if no extent was found */
/* Generic search thanks to the file system cache */
static int
hfs_move_extent_starting_at (PedFileSystem *fs, unsigned int *ptr_fblock,
			     unsigned int *ptr_to_fblock, 
			     HfsCPrivateCache* cache)
{
	HfsCPrivateExtent*	ref;
	unsigned int		old_start, new_start;
	
	/* Reference search powered by the cache... */
	/* This is the optimisation secret :) */
	ref = hfsc_cache_search_extent(cache, *ptr_fblock);
	if (!ref) return 0; /* not found */

	old_start = *ptr_fblock;
	new_start = hfs_do_move(fs, ptr_fblock, ptr_to_fblock, cache, ref);
	if (new_start == (unsigned int) -1) return -1;
	if (new_start > old_start) { /* detect 2 pass reloc */
		new_start = hfs_do_move(fs,&new_start,ptr_to_fblock,cache,ref);
		if (new_start == (unsigned int) -1 || new_start > old_start)
			return -1;
	}

	/* allocation bitmap save is not atomic with data relocation */
	/* so we only do it a few times, and without syncing */
	/* The unmounted bit protect us anyway */
	hfs_save_allocation(fs);
	return 1;
}

static int
hfs_cache_from_mdb(HfsCPrivateCache* cache, PedFileSystem* fs,
		   PedTimer* timer)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	HfsExtDescriptor*	extent;
	unsigned int		j;

	extent = priv_data->mdb->extents_file_rec;
    	for (j = 0; j < HFS_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE16_TO_CPU(extent[j].start_block),
			PED_BE16_TO_CPU(extent[j].block_count),
			0, /* unused for mdb */
			((uint8_t*)extent) - ((uint8_t*)priv_data->mdb),
			1, /* load/save only 1 sector */
			CR_PRIM_EXT,
			j )
		   )
			return 0;
	}

	extent = priv_data->mdb->catalog_file_rec;
	for (j = 0; j < HFS_EXT_NB; ++j) {
		if (!extent[j].block_count) break;
		if (!hfsc_cache_add_extent(
			cache,
			PED_BE16_TO_CPU(extent[j].start_block),
			PED_BE16_TO_CPU(extent[j].block_count),
			0,
			((uint8_t*)extent) - ((uint8_t*)priv_data->mdb),
			1,
			CR_PRIM_CAT,
			j )
		   )
			return 0;
	}

	return 1;
}

static int
hfs_cache_from_catalog(HfsCPrivateCache* cache, PedFileSystem* fs,
		   PedTimer* timer)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	uint8_t			node[PED_SECTOR_SIZE_DEFAULT];
	HfsHeaderRecord*	header;
	HfsNodeDescriptor*	desc = (HfsNodeDescriptor*) node;
	HfsCatalogKey*		catalog_key;
	HfsCatalog*		catalog_data;
	HfsExtDescriptor*	extent;
	unsigned int		leaf_node, record_number;
	unsigned int		i, j;

	if (!priv_data->catalog_file->sect_nb) {
		ped_exception_throw (
			PED_EXCEPTION_INFORMATION,
			PED_EXCEPTION_OK,
			_("This HFS volume has no catalog file.  "
			  "This is very unusual!"));
		return 1;
	}

	if (!hfs_file_read_sector (priv_data->catalog_file, node, 0))
		return 0;
	header = (HfsHeaderRecord*)(node +  PED_BE16_TO_CPU(*((uint16_t*)
						(node+(PED_SECTOR_SIZE_DEFAULT-2)))));

	for (leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
	     leaf_node;
	     leaf_node = PED_BE32_TO_CPU (desc->next)) {
		if (!hfs_file_read_sector (priv_data->catalog_file,
					   node, leaf_node))
			return 0;
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = 1; i <= record_number; ++i) {
		       /* undocumented alignement */
			unsigned int skip;
			catalog_key = (HfsCatalogKey*) (node + PED_BE16_TO_CPU(
				*((uint16_t*)(node+(PED_SECTOR_SIZE_DEFAULT - 2*i)))));
			skip = (1 + catalog_key->key_length + 1) & ~1;
			catalog_data = (HfsCatalog*)( ((uint8_t*)catalog_key)
							+ skip );
			/* check for obvious error in FS */
			if (((uint8_t*)catalog_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)catalog_data - node
				>= PED_SECTOR_SIZE_DEFAULT 
				   - 2 * (signed)(record_number+1))) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("The file system contains errors."));
				return 0;
			}

			if (catalog_data->type != HFS_CAT_FILE) continue;

			extent = catalog_data->sel.file.extents_data;
			for (j = 0; j < HFS_EXT_NB; ++j) {
				if (!extent[j].block_count) break;
				if (!hfsc_cache_add_extent(
					cache,
					PED_BE16_TO_CPU(extent[j].start_block),
					PED_BE16_TO_CPU(extent[j].block_count),
					leaf_node,
					(uint8_t*)extent - node,
					1, /* hfs => btree block = 512 b */
					CR_BTREE_CAT,
					j )
				   )
					return 0;
			}

			extent = catalog_data->sel.file.extents_res;
			for (j = 0; j < HFS_EXT_NB; ++j) {
				if (!extent[j].block_count) break;
				if (!hfsc_cache_add_extent(
					cache,
					PED_BE16_TO_CPU(extent[j].start_block),
					PED_BE16_TO_CPU(extent[j].block_count),
					leaf_node,
					(uint8_t*)extent - node,
					1, /* hfs => btree block = 512 b */
					CR_BTREE_CAT,
					j )
				   )
					return 0;
			}
		}
	}

	return 1;
}

static int
hfs_cache_from_extent(HfsCPrivateCache* cache, PedFileSystem* fs,
		   PedTimer* timer)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	uint8_t			node[PED_SECTOR_SIZE_DEFAULT];
	HfsHeaderRecord*	header;
	HfsNodeDescriptor*	desc = (HfsNodeDescriptor*) node;
	HfsExtentKey*		extent_key;
	HfsExtDescriptor*	extent;
	unsigned int		leaf_node, record_number;
	unsigned int		i, j;

	if (!priv_data->extent_file->sect_nb) {
		ped_exception_throw (
			PED_EXCEPTION_INFORMATION,
			PED_EXCEPTION_OK,
			_("This HFS volume has no extents overflow "
			  "file.  This is quite unusual!"));
		return 1;
	}

	if (!hfs_file_read_sector (priv_data->extent_file, node, 0))
		return 0;
	header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
						(node+(PED_SECTOR_SIZE_DEFAULT-2))))));

	for (leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
	     leaf_node;
	     leaf_node = PED_BE32_TO_CPU (desc->next)) {
		if (!hfs_file_read_sector (priv_data->extent_file, node,
					   leaf_node))
			return 0;
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = 1; i <= record_number; i++) {
			uint8_t	where;
			extent_key = (HfsExtentKey*)
					(node + PED_BE16_TO_CPU(*((uint16_t *)
					      (node+(PED_SECTOR_SIZE_DEFAULT - 2*i)))));
			/* size is cst */
			extent = (HfsExtDescriptor*)(((uint8_t*)extent_key)
						       + sizeof (HfsExtentKey));
			/* check for obvious error in FS */
			if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)extent - node 
			        >= PED_SECTOR_SIZE_DEFAULT
				   - 2 * (signed)(record_number+1))) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("The file system contains errors."));
				return 0;
			}

			switch (extent_key->file_ID) {
			    case PED_CPU_TO_BE32 (HFS_XTENT_ID) :
				if (ped_exception_throw (
					PED_EXCEPTION_WARNING,
					PED_EXCEPTION_IGNORE_CANCEL,
					_("The extents overflow file should not"
					  " contain its own extents!  You "
					  "should check the file system."))
						!= PED_EXCEPTION_IGNORE)
					return 0;
				where = CR_BTREE_EXT_EXT;
				break;
			    case PED_CPU_TO_BE32 (HFS_CATALOG_ID) :
				where = CR_BTREE_EXT_CAT;
				break;
			    default :
				where = CR_BTREE_EXT_0;
				break;
			}

			for (j = 0; j < HFS_EXT_NB; ++j) {
				if (!extent[j].block_count) break;
				if (!hfsc_cache_add_extent(
					cache,
					PED_BE16_TO_CPU(extent[j].start_block),
					PED_BE16_TO_CPU(extent[j].block_count),
					leaf_node,
					(uint8_t*)extent - node,
					1, /* hfs => btree block = 512 b */
					where,
					j )
				   )
					return 0;
			}
		}
	}

	return 1;
}

/* This function cache every extents start and length stored in any
   fs structure into the adt defined in cache.[ch]
   Returns NULL on failure */
static HfsCPrivateCache*
hfs_cache_extents(PedFileSystem *fs, PedTimer* timer)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	HfsCPrivateCache*	ret;
	unsigned int		file_number, block_number;

	file_number = PED_BE32_TO_CPU(priv_data->mdb->file_count);
	block_number = PED_BE16_TO_CPU(priv_data->mdb->total_blocks);
	ret = hfsc_new_cache(block_number, file_number);
	if (!ret) return NULL;

	if (!hfs_cache_from_mdb(ret, fs, timer) ||
	    !hfs_cache_from_catalog(ret, fs, timer) ||
	    !hfs_cache_from_extent(ret, fs, timer)) {
		ped_exception_throw(
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Could not cache the file system in memory."));
		hfsc_delete_cache(ret);
		return NULL;
	}

	return ret;
}

/* This function moves file's data to compact used and free space,
   starting at fblock block */
/* return 0 on error */
int
hfs_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
			        PedTimer* timer, unsigned int to_free)
{
	PedSector		bytes_buff;
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	HfsMasterDirectoryBlock* mdb = priv_data->mdb;
	HfsCPrivateCache*	cache;
	unsigned int 		to_fblock = fblock;
	unsigned int		start = fblock;
	unsigned int		divisor = PED_BE16_TO_CPU (mdb->total_blocks)
				          + 1 - start - to_free;
	int			ret;

	PED_ASSERT (!hfs_block, return 0);

	cache = hfs_cache_extents (fs, timer);
	if (!cache)
		return 0;

	/* Calculate the size of the copy buffer :
	 * Takes BLOCK_MAX_BUFF HFS blocks, but if > BYTES_MAX_BUFF
	 * takes the maximum number of HFS blocks so that the buffer
	 * will remain smaller than or equal to BYTES_MAX_BUFF, with
	 * a minimum of 1 HFS block */
	bytes_buff = PED_BE32_TO_CPU (priv_data->mdb->block_size)
		     * (PedSector) BLOCK_MAX_BUFF;
	if (bytes_buff > BYTES_MAX_BUFF) {
		hfs_block_count = BYTES_MAX_BUFF
				 / PED_BE32_TO_CPU (priv_data->mdb->block_size);
		if (!hfs_block_count)
			hfs_block_count = 1;
		bytes_buff = (PedSector) hfs_block_count
			     * PED_BE32_TO_CPU (priv_data->mdb->block_size);
	} else
		hfs_block_count = BLOCK_MAX_BUFF;

	/* If the cache code requests more space, give it to him */
	if (bytes_buff < hfsc_cache_needed_buffer (cache))
		bytes_buff = hfsc_cache_needed_buffer (cache);

	hfs_block = (uint8_t*) ped_malloc (bytes_buff);
	if (!hfs_block)
		goto error_cache;

	if (!hfs_read_bad_blocks (fs)) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Bad blocks list could not be loaded."));
		goto error_alloc;
	}

	while (fblock < PED_BE16_TO_CPU (mdb->total_blocks)) {
		if (TST_BLOC_OCCUPATION(priv_data->alloc_map,fblock)
		    && (!hfs_is_bad_block (fs, fblock))) {
			if (!(ret = hfs_move_extent_starting_at (fs, &fblock,
						&to_fblock, cache)))
				to_fblock = ++fblock;
			else if (ret == -1) {
				ped_exception_throw (
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("An error occurred during extent "
					  "relocation."));
				goto error_alloc;
			}
		} else {
			fblock++;
		}

		ped_timer_update(timer, (float)(to_fblock - start)/divisor);
	}

	ped_free (hfs_block); hfs_block = NULL; hfs_block_count = 0;
	hfsc_delete_cache (cache);
	return 1;

error_alloc:
	ped_free (hfs_block); hfs_block = NULL; hfs_block_count = 0;
error_cache:
	hfsc_delete_cache (cache);
	return 0;
}

#endif /* !DISCOVER_ONLY */
