/*
    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

    I can also be contacted at:

    Andrew Clausen
    18 Shaw St
    Ashwood, 3147
    Victoria, Australia

*/

#include <config.h>
#include "fat.h"
#include "traverse.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef DISCOVER_ONLY

#if 0
/* extremely ugly hack: stick everything that obviously isn't an unmovable file
 * in here.  Note: DAT is a bit dubious.  Unfortunately, it's used by the
 * registry, so it'll be all over the place :-(
 */
static char*	movable_extensions[] = {
	"",
	"1ST",
	"AVI",
	"BAK", "BAT", "BMP",
	"CFG", "COM", "CSS",
	"DAT", "DLL", "DOC", "DRV",
	"EXE",
	"FAQ", "FLT", "FON",
	"GID", "GIF",
	"HLP", "HTT", "HTM",
	"ICO", "INI",
	"JPG",
	"LNK", "LOG",
	"KBD",
	"ME", "MID", "MSG",
	"OCX", "OLD",
	"PIF", "PNG", "PRV",
	"RTF",
	"SCR", "SYS",
	"TMP", "TTF", "TXT",
	"URL",
	"WAV",
	"VBX", "VOC", "VXD",
	NULL
};

static char*
get_extension (char* file_name)
{
	char*		ext;

	ext = strrchr (file_name, '.');
	if (!ext)
		return "";
	if (strchr (ext, '\\'))
		return "";
	return ext + 1;
}

static int
is_movable_system_file (char* file_name)
{
	char*		ext = get_extension (file_name);
	int		i;

	for (i = 0; movable_extensions [i]; i++) {
		if (strcasecmp (ext, movable_extensions [i]) == 0)
			return 1;
	}

	return 0;
}
#endif /* 0 */

/*
    prints out the sequence of clusters for a given file chain, beginning
    at start_cluster.
*/
#ifdef PED_VERBOSE
static void
print_chain (PedFileSystem* fs, FatCluster start)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
	FatCluster	clst;
	int		this_row;

	this_row = 0;
	for (clst = start; !fat_table_is_eof (fs_info->fat, clst);
	     clst = fat_table_get (fs_info->fat, clst)) {
		printf ("  %d", (int) clst);
		if (++this_row == 7) {
                        putchar ('\n');
			this_row = 0;
		}
	}
	putchar ('\n');
}
#endif /* PED_VERBOSE */

static PedSector
remainder_round_up (PedSector a, PedSector b)
{
	PedSector	result;

	result = a % b;
	if (!result)
		result = b;
	return result;
}

/*
    traverse the FAT for a file/directory, marking each entry's flag
    to "flag".
*/
static int
flag_traverse_fat (PedFileSystem* fs, const char* chain_name, FatCluster start,
		   FatClusterFlag flag, PedSector size)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
	FatCluster	clst;
	FatCluster	prev_clst;
	int		last_cluster_usage;
	FatCluster	chain_length = 0;

	if (fat_table_is_eof (fs_info->fat, start)) {
		if (ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Bad directory entry for %s: first cluster is the "
			  "end of file marker."),
			chain_name)
				!= PED_EXCEPTION_IGNORE)
			return 0;
	}

	for (prev_clst = clst = start; !fat_table_is_eof (fs_info->fat, clst);
	     prev_clst = clst, clst = fat_table_get (fs_info->fat, clst)) {
		chain_length++;
		if (!clst) {
			ped_exception_throw (PED_EXCEPTION_FATAL,
				PED_EXCEPTION_CANCEL,
				_("Bad FAT: unterminated chain for %s.  You "
				  "should run dosfsck or scandisk."),
				chain_name);
			return 0;
		}

		if (clst >= fs_info->fat->cluster_count + 2) {
			ped_exception_throw (PED_EXCEPTION_FATAL,
				PED_EXCEPTION_CANCEL,
				_("Bad FAT: cluster %d outside file system "
				  "in chain for %s.  You should run dosfsck "
				  "or scandisk."),
				(int) clst, chain_name);
			return 0;
		}

		if (fs_info->cluster_info [clst].flag != FAT_FLAG_FREE ) {
			ped_exception_throw (PED_EXCEPTION_FATAL,
				PED_EXCEPTION_CANCEL,
				_("Bad FAT: cluster %d is cross-linked for "
				  "%s.  You should run dosfsck or scandisk."),
				(int) clst, chain_name);
			return 0;
		}

		if (flag == FAT_FLAG_DIRECTORY)
			fs_info->total_dir_clusters++;

		fs_info->cluster_info [clst].flag = flag;
		fs_info->cluster_info [clst].units_used = 0;	/* 0 == 64 */
	}

	if (size
	    && chain_length
	    		!= ped_div_round_up (size, fs_info->cluster_sectors)) {
		if (ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("%s is %dk, but it has %d clusters (%dk)."),
			chain_name,
			(int) size / 2,
			(int) chain_length,
			(int) chain_length * fs_info->cluster_sectors / 2)
				!= PED_EXCEPTION_IGNORE)
			return 0;
	}

	last_cluster_usage
		= ped_div_round_up (64 * remainder_round_up (size,
						fs_info->cluster_sectors),
				fs_info->cluster_sectors);

	fs_info->cluster_info [prev_clst].units_used = last_cluster_usage;

	return 1;
}

/*
    recursively traverses a directory, flagging all clusters in the process.
    It frees the traverse_info structure before returning.
*/
static int
flag_traverse_dir (FatTraverseInfo* trav_info) {
	PedFileSystem*		fs = trav_info->fs;
	FatDirEntry*		this_entry;
	FatTraverseInfo*	subdir_trav_info;
	char			file_name [512];
	char*			file_name_start;
	FatCluster		first_cluster;
	PedSector		size;

	PED_ASSERT (trav_info != NULL, return 0);

	strcpy (file_name, trav_info->dir_name);
	file_name_start = file_name + strlen (file_name);

	while ( (this_entry = fat_traverse_next_dir_entry (trav_info)) ) {
		if (fat_dir_entry_is_null_term (this_entry))
			break;
		if (!fat_dir_entry_has_first_cluster (this_entry, fs))
			continue;
		if (this_entry->name [0] == '.')
			continue;	/* skip . and .. entries */

		fat_dir_entry_get_name (this_entry, file_name_start);
		first_cluster = fat_dir_entry_get_first_cluster(this_entry, fs);
		size = ped_div_round_up (fat_dir_entry_get_length (this_entry),
					 512);

#ifdef PED_VERBOSE
		printf ("%s: ", file_name);
		print_chain (fs, first_cluster);
#endif

#if 0
		if (fat_dir_entry_is_system_file (this_entry)
		    && !is_movable_system_file (file_name)) {
                        PedExceptionOption ex_status;
			ex_status = ped_exception_throw (
				PED_EXCEPTION_WARNING,
				PED_EXCEPTION_IGNORE_CANCEL,
				_("The file %s is marked as a system file.  "
				"This means moving it could cause some "
				"programs to stop working."),
				file_name);

			switch (ex_status) {
				case PED_EXCEPTION_CANCEL:
					return 0;

				case PED_EXCEPTION_UNHANDLED:
					ped_exception_catch ();
				case PED_EXCEPTION_IGNORE:
			}
		}
#endif /* 0 */

		if (fat_dir_entry_is_directory (this_entry)) {
			if (!flag_traverse_fat (fs, file_name, first_cluster,
						FAT_FLAG_DIRECTORY, size))
				return 0;

			subdir_trav_info = fat_traverse_directory (trav_info,
								   this_entry);
			if (!subdir_trav_info)
				return 0;
			if (!flag_traverse_dir (subdir_trav_info))
				return 0;
		} else if (fat_dir_entry_is_file (this_entry)) {
			if (!flag_traverse_fat (fs, file_name, first_cluster,
						FAT_FLAG_FILE, size)) 
				return 0;
		}
	}

	fat_traverse_complete (trav_info);
	return 1;
}

static void
_mark_bad_clusters (PedFileSystem* fs)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
	FatCluster	cluster;

	for (cluster = 2; cluster < fs_info->cluster_count + 2; cluster++) {
		if (fat_table_is_bad (fs_info->fat, cluster))
			fs_info->cluster_info [cluster].flag = FAT_FLAG_BAD;
	}
}

/*  
    fills in cluster_info.  Each FAT entry (= cluster) is flagged as either
    FAT_FLAG_FREE, FAT_FLAG_FILE or FAT_FLAG_DIRECTORY.

    Also, the fraction of each cluster (x/64) is recorded
*/
int
fat_collect_cluster_info (PedFileSystem* fs) {
	FatSpecific*		fs_info = FAT_SPECIFIC (fs);
	FatTraverseInfo*	trav_info;
    
	/* set all clusters to unused as a default */
	memset (fs_info->cluster_info, 0, fs_info->fat->cluster_count + 2);
	fs_info->total_dir_clusters = 0;

	if (fs_info->fat_type == FAT_TYPE_FAT32) {
		trav_info = fat_traverse_begin (fs, fs_info->root_cluster,
						"\\");
		if (!flag_traverse_dir (trav_info))
			return 0;
		if (!flag_traverse_fat (fs, "\\", fs_info->root_cluster,
                                        FAT_FLAG_DIRECTORY, 0))
			return 0;
	} else {
		trav_info = fat_traverse_begin (fs, FAT_ROOT, "\\");
		if (!flag_traverse_dir (trav_info))
			return 0;
	}

	_mark_bad_clusters (fs);
	return 1;
}

FatClusterFlag
fat_get_cluster_flag (PedFileSystem* fs, FatCluster cluster)
{
	FatSpecific*		fs_info = FAT_SPECIFIC (fs);

	return fs_info->cluster_info [cluster].flag;
}

PedSector
fat_get_cluster_usage (PedFileSystem* fs, FatCluster cluster)
{
	FatSpecific*		fs_info = FAT_SPECIFIC (fs);
	int			fraction;

	if (fs_info->cluster_info [cluster].flag == FAT_FLAG_FREE)
		return 0;

	fraction = fs_info->cluster_info [cluster].units_used;
	if (fraction == 0)
		fraction = 64;

	return fraction * fs_info->cluster_sectors / 64;
}

FatClusterFlag
fat_get_fragment_flag (PedFileSystem* fs, FatFragment frag)
{
	FatSpecific*	fs_info = FAT_SPECIFIC (fs);
	FatCluster	cluster = fat_frag_to_cluster (fs, frag);
	FatFragment	offset = frag % fs_info->cluster_frags;
	FatFragment	last_frag_used;
	FatClusterFlag	flag;

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

	flag = fat_get_cluster_flag (fs, cluster);
	if (flag != FAT_FLAG_FILE && flag != FAT_FLAG_DIRECTORY)
		return flag;
	last_frag_used = (fat_get_cluster_usage (fs, cluster) - 1)
				/ fs_info->frag_sectors;
	if (offset > last_frag_used)
		return FAT_FLAG_FREE;
	else
		return flag;
}

int
fat_is_fragment_active (PedFileSystem* fs, FatFragment frag)
{
	switch (fat_get_fragment_flag (fs, frag)) {
		case FAT_FLAG_FREE:
		case FAT_FLAG_BAD:
			return 0;

		case FAT_FLAG_FILE:
		case FAT_FLAG_DIRECTORY:
			return 1;
	}
	return 0;
}

#endif /* !DISCOVER_ONLY */

