/*
    libparted
    Copyright (C) 1998, 1999, 2000, 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 <parted/endian.h>
#include "fat.h"

#ifndef DISCOVER_ONLY

FatTable*
fat_table_new (FatType fat_type, FatCluster size)
{
	FatTable*	ft;
	int		entry_size = fat_table_entry_size (fat_type);

	ft = (FatTable*) ped_malloc (sizeof (FatTable));
	if (!ft) return NULL;

	ft->cluster_count = ft->free_cluster_count = size - 2;

/* ensure there's some free room on the end, to finish off the sector */
	ft->size = ped_div_round_up (size * entry_size, 512) * 512 / entry_size;
	ft->fat_type = fat_type;
	ft->raw_size = ft->size * entry_size;

	ft->table = ped_malloc (ft->raw_size);
	if (!ft->table) {
		ped_free (ft);
		return NULL;
	}

	fat_table_clear (ft);
	return ft;
}

void
fat_table_destroy (FatTable* ft)
{
	ped_free (ft->table);
	ped_free (ft);
}

FatTable*
fat_table_duplicate (const FatTable* ft)
{
	FatTable*	dup;

	dup = fat_table_new (ft->fat_type, ft->size);
	if (!dup) return NULL;

	dup->cluster_count	= ft->cluster_count;
	dup->free_cluster_count	= ft->free_cluster_count;
	dup->bad_cluster_count	= ft->bad_cluster_count;
	dup->last_alloc		= ft->last_alloc;

	memcpy (dup->table, ft->table, ft->raw_size);

	return dup;
}

void
fat_table_clear (FatTable* ft)
{
	memset (ft->table, 0, ft->raw_size);

	fat_table_set (ft, 0, 0x0ffffff8);
	fat_table_set (ft, 1, 0x0fffffff);

	ft->free_cluster_count = ft->cluster_count;
	ft->bad_cluster_count = 0;
	ft->last_alloc = 1;
}

int
fat_table_set_cluster_count (FatTable* ft, FatCluster new_cluster_count)
{
	PED_ASSERT (new_cluster_count + 2 <= ft->size, return 0);

	ft->cluster_count = new_cluster_count;
	return fat_table_count_stats (ft);
}

int
fat_table_count_stats (FatTable* ft)
{
	FatCluster	i;

	PED_ASSERT (ft->cluster_count + 2 <= ft->size, return 0);

	ft->free_cluster_count = 0;
	ft->bad_cluster_count = 0;

	for (i=2; i < ft->cluster_count + 2; i++) {
		if (fat_table_is_available (ft, i))
			ft->free_cluster_count++;
		if (fat_table_is_bad (ft, i))
			ft->bad_cluster_count++;
	}
	return 1;
}

int
fat_table_read (FatTable* ft, const PedFileSystem* fs, int table_num)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (fs);

	PED_ASSERT (ft->raw_size >= fs_info->fat_sectors * 512, return 0);

	memset (ft->table, 0, ft->raw_size);

        if (!ped_geometry_read (fs->geom, (void *) ft->table,
				fs_info->fat_offset
					+ table_num * fs_info->fat_sectors,
				fs_info->fat_sectors))
		return 0;

        if ( *((unsigned char*) ft->table) != fs_info->boot_sector.media) {
		if (ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("FAT %d media %x doesn't match the boot sector's "
			  "media %x.  You should probably run scandisk."),
			(int) table_num + 1,
			(int) *((unsigned char*) ft->table),
			(int) fs_info->boot_sector.media)
				!= PED_EXCEPTION_IGNORE)
			return 0;
        }

	ft->cluster_count = fs_info->cluster_count;

	fat_table_count_stats (ft);

	return 1;
}

int
fat_table_write (const FatTable* ft, PedFileSystem* fs, int table_num)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (fs);

	PED_ASSERT (ft->raw_size >= fs_info->fat_sectors * 512, return 0);

        if (!ped_geometry_write (fs->geom, (void *) ft->table,
				 fs_info->fat_offset
					+ table_num * fs_info->fat_sectors,
				 fs_info->fat_sectors))
		return 0;
	if (!ped_geometry_sync (fs->geom))
		return 0;

	return 1;
}

int
fat_table_write_all (const FatTable* ft, PedFileSystem* fs)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
	int		i;

	for (i = 0; i < fs_info->fat_table_count; i++) {
		if (!fat_table_write (ft, fs, i))
			return 0;
	}

	return 1;
}

int
fat_table_compare (const FatTable* a, const FatTable* b)
{
	FatCluster	i;

	if (a->cluster_count != b->cluster_count)
		return 0;

	for (i = 0; i < a->cluster_count + 2; i++) {
		if (fat_table_get (a, i) != fat_table_get (b, i))
			return 0;
	}

	return 1;
}

static int
_test_code_available (const FatTable* ft, FatCluster code)
{
	return code == 0;
}

static int
_test_code_bad (const FatTable* ft, FatCluster code)
{
	switch (ft->fat_type) {
                case FAT_TYPE_FAT12:
                if (code == 0xff7) return 1;
                break;

		case FAT_TYPE_FAT16:
		if (code == 0xfff7) return 1;
		break;

		case FAT_TYPE_FAT32:
		if (code == 0x0ffffff7) return 1;
		break;
	}
	return 0;
}

static int
_test_code_eof (const FatTable* ft, FatCluster code)
{
	switch (ft->fat_type) {
                case FAT_TYPE_FAT12:
                if (code >= 0xff7) return 1;
                break;

		case FAT_TYPE_FAT16:
		if (code >= 0xfff7) return 1;
		break;

		case FAT_TYPE_FAT32:
		if (code >= 0x0ffffff7) return 1;
		break;
	}
	return 0;
}

void
_update_stats (FatTable* ft, FatCluster cluster, FatCluster value)
{
	if (_test_code_available (ft, value)
	    && !fat_table_is_available (ft, cluster)) {
		ft->free_cluster_count++;
		if (fat_table_is_bad (ft, cluster))
			ft->bad_cluster_count--;
	}

	if (!_test_code_available (ft, value)
	    && fat_table_is_available (ft, cluster)) {
		ft->free_cluster_count--;
		if (_test_code_bad (ft, cluster))
			ft->bad_cluster_count--;
	}
}

int
fat_table_set (FatTable* ft, FatCluster cluster, FatCluster value)
{
	if (cluster >= ft->cluster_count + 2) {
		ped_exception_throw (PED_EXCEPTION_BUG,
				     PED_EXCEPTION_CANCEL,
				     _("fat_table_set: cluster %ld outside "
				       "file system"),
				     (long) cluster);
		return 0;
	}

	_update_stats (ft, cluster, value);

	switch (ft->fat_type) {
                case FAT_TYPE_FAT12:
                PED_ASSERT (0, (void) 0);
                break;

		case FAT_TYPE_FAT16:
		((unsigned short *) ft->table) [cluster]
			= PED_CPU_TO_LE16 (value);
		break;

		case FAT_TYPE_FAT32:
		((unsigned int *) ft->table) [cluster]
			= PED_CPU_TO_LE32 (value);
		break;
	}
	return 1;
}

FatCluster 
fat_table_get (const FatTable* ft, FatCluster cluster)
{
	if (cluster >= ft->cluster_count + 2) {
		ped_exception_throw (PED_EXCEPTION_BUG,
				     PED_EXCEPTION_CANCEL,
				     _("fat_table_get: cluster %ld outside "
				       "file system"),
				     (long) cluster);
		exit (1);	/* FIXME */
	}

	switch (ft->fat_type) {
                case FAT_TYPE_FAT12:
                PED_ASSERT (0, (void) 0);
                break;

		case FAT_TYPE_FAT16:
		return PED_LE16_TO_CPU
			(((unsigned short *) ft->table) [cluster]);

		case FAT_TYPE_FAT32:
		return PED_LE32_TO_CPU
			(((unsigned int *) ft->table) [cluster]);
	}

	return 0;
}

FatCluster
fat_table_alloc_cluster (FatTable* ft)
{
	FatCluster	i;
	FatCluster	cluster;

/* hack: assumes the first two FAT entries are marked as used (which they
 * always should be)
 */
	for (i=1; i < ft->cluster_count + 1; i++) {
		cluster = (i + ft->last_alloc) % ft->cluster_count;
		if (fat_table_is_available (ft, cluster)) {
			ft->last_alloc = cluster;
			return cluster;
		}
	}

	ped_exception_throw (PED_EXCEPTION_ERROR,
			     PED_EXCEPTION_CANCEL,
			     _("fat_table_alloc_cluster: no free clusters"));
	return 0;
}

FatCluster
fat_table_alloc_check_cluster (FatTable* ft, PedFileSystem* fs)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
	FatCluster	result;

	while (1) {
		result = fat_table_alloc_cluster (ft);
		if (!result)
			return 0;
		if (fat_read_cluster (fs, fs_info->buffer, result))
			return result;
		fat_table_set_bad (ft, result);
	}
}

/*
    returns true if <cluster> is marked as bad
*/
int
fat_table_is_bad (const FatTable* ft, FatCluster cluster)
{
	return _test_code_bad (ft, fat_table_get (ft, cluster));
}

/*
    returns true if <cluster> represents an EOF marker
*/
int
fat_table_is_eof (const FatTable* ft, FatCluster cluster)
{
	return _test_code_eof (ft, cluster);
}

/*
    returns true if <cluster> is available.
*/
int
fat_table_is_available (const FatTable* ft, FatCluster cluster)
{
	return _test_code_available (ft, fat_table_get (ft, cluster));
}

/*
    returns true if <cluster> is empty.  Note that this includes bad clusters.
*/
int
fat_table_is_empty (const FatTable* ft, FatCluster cluster)
{
	return fat_table_is_available (ft, cluster)
		|| fat_table_is_bad (ft, cluster);
}

/*
    returns true if <cluster> is being used for something constructive.
*/
int
fat_table_is_active (const FatTable* ft, FatCluster cluster)
{
	return !fat_table_is_bad (ft, cluster)
		&& !fat_table_is_available (ft, cluster);
}

/*
    marks <cluster> as the last cluster in the chain
*/
int
fat_table_set_eof (FatTable* ft, FatCluster cluster)
{

	switch (ft->fat_type) {
                case FAT_TYPE_FAT12:
                PED_ASSERT (0, (void) 0);
                break;

		case FAT_TYPE_FAT16:
		return fat_table_set (ft, cluster, 0xfff8);
        
		case FAT_TYPE_FAT32:
		return fat_table_set (ft, cluster, 0x0fffffff);
	}

	return 0;
}

/*
	Marks a clusters as unusable, due to physical disk damage.
*/
int
fat_table_set_bad (FatTable* ft, FatCluster cluster)
{
	if (!fat_table_is_bad (ft, cluster))
		ft->bad_cluster_count++;

	switch (ft->fat_type) {
                case FAT_TYPE_FAT12:
		return fat_table_set (ft, cluster, 0xff7);

		case FAT_TYPE_FAT16:
		return fat_table_set (ft, cluster, 0xfff7);
        
		case FAT_TYPE_FAT32:
		return fat_table_set (ft, cluster, 0x0ffffff7);
	}

	return 0;
}

/*
    marks <cluster> as unused/free/available
*/
int
fat_table_set_avail (FatTable* ft, FatCluster cluster)
{
	return fat_table_set (ft, cluster, 0);
}

#endif /* !DISCOVER_ONLY */

int
fat_table_entry_size (FatType fat_type)
{
	switch (fat_type) {
		case FAT_TYPE_FAT12:
		return 2;		/* FIXME: how? */

		case FAT_TYPE_FAT16:
		return 2;

		case FAT_TYPE_FAT32:
		return 4;
	}

	return 0;
}

