/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* vim: set noet ts=8 sts=8 sw=8 : */

/**
 * \file file.h
 *
 * Declare the structs to keep track of the files to be written into image.
 * These files are stored in a hash table. Two modes of operation are supported:
 * when cache inodes is enabled, the files are indexed into the table by the 
 * device and inode id in the local filesystem. This way, two different files
 * with same inode and device id are treated as if they were a single file.
 * This is usually the correct behavior, as a different file with same inode 
 * and device used to be a hard link.
 * When cache inode is disabled, indexing is done by path on local filesystem. 
 */

#ifndef FILE_H_
#define FILE_H_

#include <stdint.h>
#define FILE_HASH_NODES 2048

struct iso_file {
	unsigned int prev_img:1; /**< if the file comes from a previous image */
	char *path; /**< Path of the file on local filesystem */
	off_t size; /**< size of this file */
	ino_t ino; /**< This will be the inode number on CD of the file (RR) */
	nlink_t nlink; /**< Number of hard links of the file on CD (RR) */ 
	uint32_t block; /**< Block where this file is to be written on image */
	dev_t real_dev;
	ino_t real_ino; /**< for lookup by inode caching */
	int sort_weight;
	struct iso_file_src *src;
};

struct iso_file_hash_node {
	struct iso_file_hash_node *next;
	struct iso_file *file;
};

struct iso_file_table {
	struct iso_file_hash_node *table[FILE_HASH_NODES];
	size_t count;
	int cache_inodes; /**< 1 to index by inode number */
};

struct iso_tree_node_file;
struct ecma119_write_target;

/**
 * Create a struct that represents the specified iso_tree_node_file,
 * suitable to be stored into the table,
 */
struct iso_file *iso_file_new(struct ecma119_write_target *t, 
                              struct iso_tree_node_file*);

struct iso_file_table *iso_file_table_new(int cache_inodes);

/**
 * Clear a hash table. All iso_file structs stored will also be freed,
 * but not the path of each iso_file
 */
void iso_file_table_clear(struct iso_file_table *ft);

/**
 * Add a new file to the table.
 * \return 1 if the file is added, 0 if the file already exist on table
 */
int iso_file_table_add_file(struct iso_file_table *ft, struct iso_file *f);

struct iso_file *iso_file_table_lookup(struct iso_file_table *ft, 
                                       struct iso_tree_node_file *f);

#endif /*FILE_H_*/