#!/usr/bin/perl

use Switch;

sub trim;
sub get_value;
sub get_var;
sub get_field;

# trim($str)
# input:	a string
# output:	the trimmed string (without whitespace)
sub trim {
	$ans = $_[0];
	$ans =~ s/^\s+//; #remove leading spaces
	$ans =~ s/\s+$//; #remove trailing spaces
	return $ans;
}

# get_value($str)
# input:	a XML tag
# output:	the tag name
sub get_value {
	$start = 1 + index($_[0], ">");
	$end = rindex($_[0], "<");
	return substr($_[0], $start, ($end - $start));
}

# get_var($str, $var_name)
# input:	a XML tag and a variable name
# output:	the variable value
sub get_var {
	($str, $var_name) = @_;
	
	# trim everything until the requested variable's value
	$start = index($str, " ".$var_name."=");
	$ans = substr($str, 3 + length($var_name) + $start);

	# trim everything after the value
	$start = index($ans, "\"");
	$ans = substr($ans, 0, $start);
		
	return $ans	
}

# get_field($str)
# input:	a XML tag
# output:	the tag value
sub get_field {
	$ans =  substr($_[0], 1, (index($_[0], ">") - 1));
	if (index($ans, " ") != -1) {
		$ans =  substr($_[0], 1, (index($_[0], " ") - 1));
	}
	return $ans;
}

if ((! -e $ARGV[0]) || (-e $ARGV[1])) {
	print("Usage: rpm2ppm [FILE] [OUTPUT] [DISTRO] [VERSION]\n");
	exit(1);
}

open(rpm_package_list, $ARGV[0]);
open(ppm_package_list, ">>$ARGV[1]");

while ($line = <rpm_package_list>) 
{
	$line = trim($line);
	$field = get_field($line);

    switch ($field) {
		
		case "name" {
			$package_name = get_value($line);
			print $package_name." ";   
		}
      
		case "version" {
			$package_version = get_var($line, "ver");
			$package_revision = get_var($line, "rel");
		}
		
		case "summary" {
			$package_description = get_value($line);
		}
		
		case "size" {
			$package_size = get_var($line, "installed")."K";
		}
		
		case "location" {
			$package_path = get_var($line, "href");
			$pos = rindex($package_path, "/");
			$package_file_name = substr($package_path, (1 + $pos));
			$package_path = substr($package_path, 0, $pos);
		}
	
		case "rpm:provides" {
			$package_provides = "";
			$provides = 1;
		}
						
		case "rpm:requires" {
			$package_dependencies = "";
			$requires = 1;
		}
		
		case "rpm:entry" {
			$entry_name = get_var($line, "name");
			# filter shared libraries, architecture names and files
			if ((index($entry_name, ".so") == -1) && (index($entry_name, "(") == -1) && (index($entry_name, "/") == -1)) {
				# process packages provided by the package
				if ($provides == 1) {					
					if ($package_provides eq "") {
						$package_provides = "|".$entry_name."|";
					} else {
						$package_provides = $package_provides."|".$entry_name."|";
					}			
				} else {
					# process dependencies
					if ($requires == 1) {
						# get rid of the package's dependencies provided by the package itself (e.g mktemp and coreutils)
						if (($entry_name ne $package_name) && (index($package_provides, "|".$entry_name."|")) == -1) {
							if ($package_dependencies eq "") {
								$package_dependencies = "+".$entry_name;
							} else {
								# make sure dependencies aren't added twice
								if ((index($package_dependencies, ",+".$entry_name) == -1) && (index($package_dependencies, "+".$entry_name.",") == -1)) {
									$package_dependencies = $package_dependencies.",+".$entry_name;
								}
							}
						}
					}
				}
			}
		}
	
		case "/rpm:provides" {
			$provides = 0;
		}

		case "/rpm:requires" {
			$requires = 0;
		}
			
		# the last tag of each entry
		case "/package" {
			print ppm_package_list $package_name."-".$package_version."|".$package_name."|".$package_version."|".$package_revision."|BuildingBlock|".$package_size."|".$package_path."|".$package_file_name."|".$package_dependencies."|".$package_description."|".$ARGV[2]."|".$ARGV[3]."|\n";
		}
		
	}
}

print "\n";
close(rpm_package_list);
close(ppm_package_list);
