#
# perl/saint-data.pl
#
# SAINT data management routines.
#
require 'perl/targets.pl';
require 'perl/todo.pl';
require 'perl/facts.pl';

#
# Reset and point path names to new or existing data directory.
#
sub init_saint_data {
	local($directory);

	&clear_saint_data();
	&find_saint_data();
}

#
# Point path names to new or existing data directory.
#
sub find_saint_data {
	if ($saint_data =~ /\// ) {
		$directory = $saint_data;
	} else {
		(-d "results") || mkdir("results",0700) 
			|| die "results: invalid directory: $!\n";
		$directory = "results/$saint_data";
	}
	(-d "$directory") || mkdir("$directory",0700) 
		|| die "$saint_data: invalid directory: $!\n";

	$todo_file = "$directory/todo";
	$facts_file = "$directory/facts";
	$all_hosts_file = "$directory/all-hosts";
	$cve_file = "$directory/cve";
}

#
# Erase all in-core saint data structures.
#
sub clear_saint_data {
	&clear_all_hosts();
	&clear_facts();
	&clear_todos();
	&clear_cves();
	&clear_exclusions();
}

#
# Forget non-inference stuff we know about these hosts. We must save/reload
# the tables later, or memory will be polluted with stale inferences.
#
sub drop_saint_data {
	local($hosts) = @_;
	local($host);

	for $host (split(/\s+/, $hosts)) {
		&drop_all_hosts($host);
		&drop_old_todos($host);
		&drop_old_facts($host);
	}
}

#
# Read saint data from file. Existing in-core data is lost.
#
sub read_saint_data {

	my($exclusions_file) = &exclusion_file_path;
	&clear_saint_data();

	print "Reading $saint_data files...\n" if (-s $facts_file && $debug);

	&read_all_hosts($all_hosts_file) if -f $all_hosts_file;
	&read_facts($facts_file) if -f $facts_file;
	&read_todos($todo_file) if -f $todo_file;
	&read_cves($cve_file) if -f $cve_file;
	&read_exclusions($exclusions_file) if -f $exclusions_file;

	print "Done reading $saint_data files\n" if (-s $facts_file && $debug);
}

#
# Save saint data to file. Order may matter, in case we crash.
#
sub save_saint_data {
	&save_facts("$facts_file.new");
	rename("$facts_file.new", $facts_file)
		|| die "rename $facts_file.new -> $facts_file: $!\n";

	&save_todos("$todo_file.new");
	rename("$todo_file.new", $todo_file)
		|| die "rename $todo_file.new -> $todo_file: $!\n";

	&save_all_hosts("$all_hosts_file.new");
	rename("$all_hosts_file.new", $all_hosts_file)
		|| die "rename $all_hosts_file.new -> $all_hosts_file: $!\n";

	&save_cves("$cve_file.new");
	rename("$cve_file.new", $cve_file)
		|| die "rename $cve_file.new -> $cve_file: $!\n";
}

#
# Merge data with in-core tables.
#
sub merge_saint_data {
	my($exclusions_file) = &exclusion_file_path;

	&merge_all_hosts($all_hosts_file) if -f $all_hosts_file;
	&merge_facts($facts_file) if -f $facts_file;
	&merge_todos($todo_file) if -f $todo_file;
	&merge_cves($cve_file) if -f $cve_file;
	&merge_exclusions($exclusions_file) if -f $exclusions_file;
	&force_recalc;
}
