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

/* - if a < b, 0 if a == b, + if a > b */
/* Comparaison is done in the following order : */
/* CNID, then fork type, then start block */
/* Note that HFS implementation in linux has a bug */
/* in this function */
static int
hfs_extent_key_cmp(HfsPrivateGenericKey* a, HfsPrivateGenericKey* b)
{
	HfsExtentKey* key1 = (HfsExtentKey*) a;
	HfsExtentKey* key2 = (HfsExtentKey*) b;

	/* do NOT use a substraction, because */
	/* 0xFFFFFFFF - 1 = 0xFFFFFFFE so this */
	/* would return -2, despite the fact */
	/* 0xFFFFFFFF > 1 !!! (this is the 2.4 bug) */
	if (key1->file_ID != key2->file_ID)
		return PED_BE32_TO_CPU(key1->file_ID) <
		       PED_BE32_TO_CPU(key2->file_ID) ? 
				-1 : +1;

	if (key1->type != key2->type)
		return (int)(key1->type - key2->type);

	if (key1->start == key2->start)
		return 0;
	/* the whole thing wont work with 16 bits ints */
	/* anyway */
	return (int)( PED_BE16_TO_CPU(key1->start) - 
		      PED_BE16_TO_CPU(key2->start) );
}

/* do a B-Tree lookup */
/* read the first record immediatly inferior or egal to the given key */
/* return 0 on error */
/* record_out _must_ be large enough to receive record_size bytes */
/* WARNING : the compare function called only handle Extents BTree */
/*	     so modify this function if you want to do lookup in */
/* 	     other BTrees has well */
int
hfs_btree_search (HfsPrivateFile* b_tree_file, HfsPrivateGenericKey* key,
		  void *record_out, unsigned int record_size,
		  HfsCPrivateLeafRec* record_ref)
{
	uint8_t			node[PED_SECTOR_SIZE_DEFAULT];
	HfsHeaderRecord*	header;
	HfsNodeDescriptor*	desc = (HfsNodeDescriptor*) node;
	HfsPrivateGenericKey*	record_key = NULL;
	unsigned int		node_number, record_number;
	int			i;

	/* Read the header node */
	if (!hfs_file_read_sector(b_tree_file, node, 0))
		return 0;
	header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
						(node+(PED_SECTOR_SIZE_DEFAULT-2))))));

	/* Get the node number of the root */
	node_number = PED_BE32_TO_CPU(header->root_node);
	if (!node_number)
		return 0;

	/* Read the root node */
	if (!hfs_file_read_sector(b_tree_file, node, node_number))
		return 0;

	/* Follow the white rabbit */
	while (1) {
		record_number = PED_BE16_TO_CPU (desc->rec_nb);
		for (i = record_number; i; i--) {
			record_key = (HfsPrivateGenericKey*)
				(node + PED_BE16_TO_CPU(*((uint16_t *)
					    (node+(PED_SECTOR_SIZE_DEFAULT - 2*i)))));
			/* check for obvious error in FS */
			if (((uint8_t*)record_key - node < HFS_FIRST_REC)
			    || ((uint8_t*)record_key - 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 (hfs_extent_key_cmp(record_key, key) <= 0)
				break;
		}
		if (!i) return 0;
		if (desc->type == HFS_IDX_NODE) {
			unsigned int 	skip;

			skip = (1 + record_key->key_length + 1) & ~1;
			node_number = PED_BE32_TO_CPU (*((uint32_t *)
					(((uint8_t *) record_key) + skip)));
			if (!hfs_file_read_sector(b_tree_file, node,
						  node_number))
				return 0;
		} else 
			break;
	}

	/* copy the result if needed */
	if (record_size)
		memcpy (record_out, record_key, record_size);

	/* send record reference if needed */
	if (record_ref) {
		record_ref->node_size = 1;	/* in sectors */
		record_ref->node_number = node_number;
		record_ref->record_pos = (uint8_t*)record_key - node;
		record_ref->record_number = i;
	}

	/* success */
	return 1;
}

/* free the bad blocks linked list */
void
hfs_free_bad_blocks_list(HfsPrivateLinkExtent* first)
{
	HfsPrivateLinkExtent*	next;

	while (first) {
		next = first->next;
		ped_free (first);
		first = next;
	}
}

/* This function reads bad blocks extents in the extents file
   and store it in f.s. specific data of fs */
int
hfs_read_bad_blocks (const PedFileSystem *fs)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;

	if (priv_data->bad_blocks_loaded)
		return 1;

	{
	uint8_t			record[sizeof (HfsExtentKey) 
					       + sizeof (HfsExtDataRec)];
	HfsExtentKey		search;
	HfsExtentKey*		ret_key = (HfsExtentKey*) record;
	HfsExtDescriptor*	ret_cache = (HfsExtDescriptor*)
					     (record + sizeof (HfsExtentKey));
	unsigned int		block, last_start, first_pass = 1;

	search.key_length = sizeof (HfsExtentKey) - 1;
	search.type = HFS_DATA_FORK;
	search.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);

	last_start = -1; block = 0;
	while (1) {
		int i;

		search.start = PED_CPU_TO_BE16 (block);
		if (!hfs_btree_search (priv_data->extent_file,
				       (HfsPrivateGenericKey*) &search,
				       record, sizeof (record), NULL)
		    || ret_key->file_ID != search.file_ID
		    || ret_key->type != search.type) {
			if (first_pass)
				break;
			else
				goto errbb;
		}
		if (PED_BE16_TO_CPU (ret_key->start) == last_start)
		    break;

		last_start = PED_BE16_TO_CPU (ret_key->start);
		for (i = 0; i < HFS_EXT_NB; i++) {
			if (ret_cache[i].block_count) {
				HfsPrivateLinkExtent*	new_xt =
				   (HfsPrivateLinkExtent*) ped_malloc (
					sizeof (HfsPrivateLinkExtent));
				if (!new_xt)
					goto errbb;
				new_xt->next = priv_data->bad_blocks_xtent_list;
				memcpy(&(new_xt->extent), ret_cache+i,
					sizeof (HfsExtDescriptor));
				priv_data->bad_blocks_xtent_list = new_xt;
				priv_data->bad_blocks_xtent_nb++;
				block += PED_BE16_TO_CPU (
						ret_cache[i].block_count);
			}
		}
		first_pass = 0;
	}

	priv_data->bad_blocks_loaded = 1;
	return 1;}

errbb:	hfs_free_bad_blocks_list(priv_data->bad_blocks_xtent_list);
	priv_data->bad_blocks_xtent_list=NULL;
	priv_data->bad_blocks_xtent_nb=0;
	return 0;
}

/* This function check if fblock is a bad block */
int
hfs_is_bad_block (const PedFileSystem *fs, unsigned int fblock)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	HfsPrivateLinkExtent*	walk;

	for (walk = priv_data->bad_blocks_xtent_list; walk; walk = walk->next) {
		/* Won't compile without the strange cast ! gcc bug ? */
		/* or maybe C subtilties... */
		if ((fblock >= PED_BE16_TO_CPU (walk->extent.start_block)) && 
		    (fblock <  (unsigned int) (PED_BE16_TO_CPU (
						    walk->extent.start_block)
					       + PED_BE16_TO_CPU (
						    walk->extent.block_count))))
			return 1;
	}

	return 0;
}

/* This function returns the first sector of the last free block of an
   HFS volume we can get after a hfs_pack_free_space_from_block call */
/* On error this function returns 0 */
PedSector
hfs_get_empty_end (const PedFileSystem *fs)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	HfsMasterDirectoryBlock* mdb = priv_data->mdb;
	HfsPrivateLinkExtent*	link;
	unsigned int		block, last_bad, end_free_blocks;

	/* find the next block to the last bad block of the volume */
	if (!hfs_read_bad_blocks (fs))
		return 0;

	last_bad = 0;
	for (link = priv_data->bad_blocks_xtent_list; link; link = link->next) {
		if ((unsigned int) PED_BE16_TO_CPU (link->extent.start_block)
		    + PED_BE16_TO_CPU (link->extent.block_count) > last_bad)
			last_bad = PED_BE16_TO_CPU (link->extent.start_block)
			           + PED_BE16_TO_CPU (link->extent.block_count);
	}

	/* Count the free blocks from last_bad to the end of the volume */
	end_free_blocks = 0;
	for (block = last_bad;
	     block < PED_BE16_TO_CPU (mdb->total_blocks);
	     block++) {
		if (!TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
			end_free_blocks++;
	}

	/* Calculate the block that will by the first free at the
	   end of the volume */
	block = PED_BE16_TO_CPU (mdb->total_blocks) - end_free_blocks;

	return (PedSector) PED_BE16_TO_CPU (mdb->start_block)
		+ (PedSector) block * (PED_BE32_TO_CPU (mdb->block_size)
				       / PED_SECTOR_SIZE_DEFAULT);
}

/* return the block which should be used to pack data to have at
   least free fblock blocks at the end of the volume */
unsigned int
hfs_find_start_pack (const PedFileSystem *fs, unsigned int fblock)
{
	HfsPrivateFSData* 	priv_data = (HfsPrivateFSData*)
						fs->type_specific;
	unsigned int		block;

	for (block = PED_BE16_TO_CPU (priv_data->mdb->total_blocks) - 1;
	     block && fblock;
	     block--) {
		if (!TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
			fblock--;
	}

	while (block && !TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
		block--;
	if (TST_BLOC_OCCUPATION(priv_data->alloc_map,block))
		block++;

	return block;
}

#endif /* !DISCOVER_ONLY */
