#!/usr/bin/perl
    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
	if $running_under_some_shell;
#!/usr/bin/perl

use strict;
use File::Copy;
use File::Temp qw/ tempfile tempdir /;

my $critical_free_space_limit_abuild = 50000000;	# in Bytes

sub show_error($)
{
    my ($msg) = @_;
    
    $msg =~ s/\'/\\\'/g;
    $msg =~ s/\"/\\\"/g;
    $msg =~ s/\;/\\\;/g;
    system("xterm -hold -T \"ooo-build-package error\" -bg IndianRed1 -e /bin/sh -c \"echo $msg\"");
    die "$msg\n";
}

sub show_warning($)
{
    my ($msg) = @_;
    
    $msg =~ s/\'/\\\'/g;
    $msg =~ s/\"/\\\"/g;
    $msg =~ s/\;/\\\;/g;
    system("xterm -hold -T \"ooo-build-package warning\" -bg PaleGreen -e /bin/sh -c \"echo $msg\" &");
    print "$msg\n";
}

sub show_msg($)
{
    my ($msg) = @_;
    
    $msg =~ s/\'/\\\'/g;
    $msg =~ s/\"/\\\"/g;
    $msg =~ s/\;/\\\;/g;
    system("xterm -hold -T \"ooo-build-package warning\" -bg LightBlue1 -e /bin/sh -c \"echo $msg\" &");
    print "$msg\n";
}

sub mktemp_remote($$$)
{
    my ($host, $pattern, $mktemp_options) = @_;

    my $remote_tempdir;
    my $pattern_reg = $pattern;
    $pattern_reg =~ s/\//\\\//g;
    $pattern_reg =~ s/X/./g;
    print "pattern_reg = $pattern_reg\n";
    print ("open (MKTEMP, \"ssh -q $host mktemp $mktemp_options $pattern 2>&1 |\");");
    my $pid = open (MKTEMP, "ssh -q $host mktemp $mktemp_options $pattern 2>&1 |");
    show_error("Can't start remote mktemp") unless (defined $pid);
    while (my $line = <MKTEMP>) {
        chomp $line;
	print "$line \n";
	$remote_tempdir = "$line" if $line =~ /$pattern_reg/;
    }
    close (MKTEMP);
    show_error("Can't create remote tempdir") unless ( defined $remote_tempdir );

    return $remote_tempdir;
}

sub run_script_remote($$$)
{
    my ($host, $script) = @_;

    #locate the script
    my $pid = open (WHICH, "which $script |");
    show_error("Can't start the command \"which\" $script") unless (defined $pid);
    while (my $line = <WHICH>) {
        chomp $line;
	$script = $line if $line =~ /$script$/;
    }
    close (WHICH);

    my $script_name = $script;
    $script_name =~ s/^.*\///;
    
    # create a temporary directory on the remote machine
    my $remote_tempdir = mktemp_remote($host, "/tmp/ooo-build-remote-XXXXXX", "-d");

    # upload the script to the remote tempdir
    system("scp -q $script $host:$remote_tempdir") &&
	show_error("Can't upload $script to $host:$remote_tempdir");

    # finally start the script
    system ("ssh -q -t $host $remote_tempdir/$script_name") &&
	show_error("$host:$remote_tempdir/$script_name failed");

    # cleanup the remote tempdir
    system ("ssh -q -t $host rm -rf $remote_tempdir") &&
	show_error("Error: rm -rf on $remote_tempdir failed\n");
}

sub sync_sources($$)
{
    my ($source, $destination) = @_;
    
    print "Uploading $source to $destination...\n";
    system ("rsync -e ssh -rav --delete --progress --checksum --exclude=BUILD $source $destination") &&
	show_error("Error: rsync failed: $!");
}

sub upload_sources($)
{
    my ($p_options) = @_;
    
    unless (defined $p_options->{'do_not_update_remote_sources'}) {
	sync_sources ("$p_options->{'package_source_path'}",
		      "$p_options->{'host'}:$p_options->{'remote_tempdir'}");
    }
    
    return;
}

sub upload_prefer_rpms($)
{
    my ($p_options) = @_;
    
    if (defined $p_options->{'local_prefer_rpms'}) {
	sync_sources ("$p_options->{'local_prefer_rpms'}/*",
		      "$p_options->{'host'}:$p_options->{'remote_prefer_rpms'}");
    }

    return;
}

sub get_packages($)
{
    my ($p_options) = @_;

    if (defined $p_options->{'get_packages_path'}) {
	if (defined $p_options->{'packages'}) {
	    system ("mkdir -p $p_options->{'get_packages_path'})") && 
		show_error("Can't create direcotry $p_options->{'get_packages_path'} to get packages");
	    for my $pack (split (",",  $p_options->{'packages'})) {
		system ("scp $p_options->{'host'}:$p_options->{'remote_rpms_path'}/$pack-*.rpm $p_options->{'get_packages_path'}");
	    }
	}
	if (defined $p_options->{'devel_packages'}) {
	    system ("mkdir -p $p_options->{'get_packages_path'}/devel") &&
		show_error("Can't create direcotry $p_options->{'get_packages_path'}/devel to get devel packages");
	    for my $pack (split (",",  $p_options->{'devel_packages'})) {
		system ("scp $p_options->{'host'}:$p_options->{'remote_rpms_path'}/$pack-*.rpm $p_options->{'get_packages_path'}/devel");
	    }
	}
    }
    # successfully finished
    $p_options->{'downloaded'}="yes";
    save_status($p_options, 1);
    return;
}

sub test_remote_dir($$)
{
    my ($host, $dir) = @_;
    
    # FIXME: is there a better way to do this?
    my $err = system ("ssh -q $host test -d $dir");
    show_error("$host test -d $dir can't be started") if ($err == -1);

    # non-zero $err value meand that the directory was not found
    if ($err) {
	return 0;
    } else {
	return 1;
    }
}

sub create_remote_tempdir($)
{
    my ($p_options) = @_;
    
    unless (defined $p_options->{'remote_tempdir'}) {
	$p_options->{'remote_tempdir'} = mktemp_remote("$p_options->{'host'}", 
						       "/tmp/$p_options->{'package_source_name'}-XXXXXX",
						       "-d");
    }

    return;
}

sub remove_remote_tempdir($)
{
    my ($p_options) = @_;

    unless (defined $p_options->{'keep_remote_tempdir'}) {
	system ("ssh $p_options->{'host'} rm -rf $p_options->{'remote_tempdir'}") &&
	    show_error("Error: rm -rf $p_options->{'remote_tempdir'} failed on $p_options->{'host'}: $!");
    }

    return;
}

sub abuild_package($)
{
    my ($p_options) = @_;
    
    #FIXME: We should check the architecture of the host
    my $linux32="";
    $linux32 = "linux32" if ("$p_options->{'distro_arch'}" eq "i386");
    $linux32 = "powerpc32" if ("$p_options->{'distro_arch'}" eq "ppc");

    my $buildroot="$p_options->{'buildroot'}";
    my $build_dist="$p_options->{'distro'}";
    my $abuild_options = "";
    $abuild_options .= " --prefer-rpms=$p_options->{'remote_prefer_rpms'}" if (defined $p_options->{'remote_prefer_rpms'});
    $abuild_options .=  " --icecream=$p_options->{'jobs'}" if (defined $p_options->{'icecream'});
    $abuild_options .= " --debug=$p_options->{'debug'}" if (defined $p_options->{'debug'});
    $abuild_options .= " --prefer-rpms=$p_options->{'prefer_rpms'}" if (defined $p_options->{'prefer_rpms'});
    $abuild_options .= " $p_options->{'package_remote_sources_path'}/$p_options->{'specfile'}";
    
    print "abuild_options=$abuild_options\n";
#    system ("ssh -t $p_options->{'host'} sudo /bin/sh -c \\\". /work/src/bin/.profile\\\; echo \\\\\$PATH\\\"");
     system ("ssh -t $p_options->{'host'} $linux32 sudo /bin/sh -c \\\". /work/src/bin/.profile\\\; export BUILD_ROOT=$buildroot\\\; export BUILD_DIST=$build_dist\\\; abuild $abuild_options\\\"") &&
	show_error("Error: abuild failed at $p_options->{'host'}:$p_options->{'buildroot'}\n");
    # build successfully finished
    $p_options->{'built'}="yes";
    $p_options->{'downloaded'}="no";
    save_status($p_options, 1);
}

sub find_specfile_in_current_dir()
{
    my $dirh;
    my $specfile;

    if (opendir($dirh, "./")) {
	while (my $file = readdir ($dirh)) {
	    $file =~ /^\./ && next;     # hidden
	    $file =~ /\.spec$/ || next; # non-spec
	    unless (defined $specfile) {
		$specfile = $file;
	    } else {
		show_error("Error: More specfiles found; Please specify one on the commandline");
	    }	    
	}
	closedir($dirh);
    }

    show_error("Error: No spec file found in current directory") unless (defined $specfile);
    
    return $specfile;
}

sub find_specfile($)
{
    my ($p_options) = @_;
    
    if (defined $p_options->{'specfile_path'}) {
        $p_options->{'specfile'} = $p_options->{'specfile_path'};
        $p_options->{'specfile'} =~ s/^.*\///g;
    } else {
	$p_options->{'specfile'} = find_specfile_in_current_dir();
    }
    
    return;
}

sub find_package_sources($)
{
    my ($p_options) = @_;
    my $abs_src_path;

    if (defined $p_options->{'specfile_path'}) {
	$abs_src_path = "$p_options->{'specfile_path'}";
	# bin the specfile
	$abs_src_path =~ s/^(.*?)\/?[^\/]+$/$1/;
	# make sure that 'cd' stays in the current dir when the path is empty
	$abs_src_path = "." unless ("$abs_src_path");
	# get absolute path
	$abs_src_path = `cd $abs_src_path; pwd`;
	chomp $abs_src_path;
    } else {
	$abs_src_path = `pwd`;
	chomp $abs_src_path;
    }

    my $last_dir = $abs_src_path;
    $last_dir =~ s/^.*\///g;
    
    $p_options->{'package_source_path'} = "$abs_src_path";
    $p_options->{'package_source_name'} = "$last_dir";

    return;
}

sub set_package_name($)
{
    my ($p_options) = @_;
    
    $p_options->{'package_name'} = $p_options->{'specfile'};
    $p_options->{'package_name'} =~ s/.spec$//;
    
    return;
}


sub set_package_remote_sources_path($)
{
    my ($p_options) = @_;
    # $p_options->{'package_source_name'}" must be in sync with upload_sources function
    $p_options->{'package_remote_sources_path'} = "$p_options->{'remote_tempdir'}/$p_options->{'package_source_name'}";
    return;
}

sub set_remote_prefer_rpms_path($)
{
    my ($p_options) = @_;


    if ($p_options->{'local_prefer_rpms'}) {
	(-d $p_options->{'local_prefer_rpms'}) || show_error("Error: The path $p_options->{'local_prefer_rpms'} defined by --prefer-rpms is not a directory\n");
    }
    # FIXME: we will always create the remote_prefer_rpms directory because we want to share it for the split OOo build
    unless (defined $p_options->{'remote_prefer_rpms'}) {
        $p_options->{'remote_prefer_rpms'} = mktemp_remote("$p_options->{'host'}", "$p_options->{'remote_tempdir'}/prefer-rpms-XXXX", "-d");
    }

    return;
}


sub check_free_space($$$)
{
    my ($host, $dir, $critical_limit) = @_;

    my $free_space;
    my $pid = open (DF, "ssh $host df $dir |");
    show_error("Can't start \"df\" on $host: $!\n") unless (defined $pid);
    while (my $line = <DF>) {
        chomp $line;
	if ($line =~ m/\S+\s+\S+\s+\S+\s+(\S+)\s+\S+\s+\/.*/) {
	    $free_space = $1;
	}
    }
    close (DF);

    if (defined $free_space) {
	if ($free_space < $critical_limit) {
	    my $free_space_mb = int($free_space/1000000);
	    show_warning("Warning: There is only ${free_space_mb}MB free space left on $host:$dir\n");
	}
    } else {
	show_warning("Warning: Failed to check free space on $host:$dir\n");
    }

    return;
}

sub set_packdir_names($)
{
    my ($p_options) = @_;

    # define some useful prefixes and suffixes
    my $packdir_basename = $p_options->{'package_name'};
    my $buildroot_suffix = "";

    if ($packdir_basename =~ /^OpenOffice_org(-.*)?/) {
	$packdir_basename = "ooo";
	# FIXME: an ugly hack to differ the split and non-split builds
	if ($1) {
		$buildroot_suffix = "$1";
	} elsif (-e "$p_options->{'package_source_path'}/OpenOffice_org-i18n.spec") {
	    $buildroot_suffix = "-devel";
	} elsif (-e "$p_options->{'package_source_path'}/OpenOffice_org-i18n-group1.spec") {
	    $buildroot_suffix = "-devel";
	} elsif (-e "$p_options->{'package_source_path'}/OpenOffice_org-l10n-group1.spec") {
	    $buildroot_suffix = "-devel";
	}
    }

    my $min_suffix="";
    $min_suffix=".min" if (defined $p_options->{'min'});
	
    my $buildid_suffix="";
    $buildid_suffix="-$p_options->{'buildid'}" if (defined $p_options->{'buildid'});

    # packdir
    my $packdir;
    if (defined $p_options->{'ptf'}) {
	$packdir = "$packdir_basename-ptf-$p_options->{'bugid'}$buildid_suffix";
    } elsif (defined $p_options->{'security'}) {
	$packdir = "$packdir_basename-sec$min_suffix$buildid_suffix-$p_options->{'distro'}";
    } else {
	$packdir = "$packdir_basename-$p_options->{'version'}$min_suffix$buildid_suffix-$p_options->{'distro'}";
    }

    # buildroot
    if (defined $p_options->{'buildroot'}) {
	$p_options->{'buildroot_name'} = "$p_options->{'buildroot'}";
	$p_options->{'buildroot_name'} =~ s/^.*\///g;
    } else {
	$p_options->{'buildroot_name'} = "$packdir$buildroot_suffix";
	$p_options->{'buildroot'} = "/abuild/$p_options->{'buildroot_name'}";
    }

    # define diretory where to get the final packages
    if (defined $p_options->{'get_packages_path_prefix'}) {
	$p_options->{'get_packages_path'} = "$p_options->{'get_packages_path_prefix'}/$packdir";
    }

    return;
}

sub check_buildroot($)
{
    my ($p_options) = @_;

    unless (defined $p_options->{'clean'} || defined $p_options->{'force'}) {
	my $result = test_remote_dir("$p_options->{'host'}", "$p_options->{'buildroot'}");
	if (test_remote_dir("$p_options->{'host'}", "$p_options->{'buildroot'}")) {
	    show_error ("Error: \"$p_options->{'host'}:$p_options->{'buildroot'}\" already exists; You might use either --clean or --force");
	}
    }

    return;
}

sub set_rpms_paths($)
{
    my ($p_options) = @_;
    
    $p_options->{'remote_rpms_path'} = "$p_options->{'buildroot'}/usr/src/packages/RPMS/$p_options->{'rpm_arch'}";
}


sub set_package_version($)
{
    my ($p_options) = @_;
    my $version_reg;
    
    if ($p_options->{'package_name'} =~ m/^OpenOffice_org$/ ||
        $p_options->{'package_name'} =~ m/^OpenOffice_org-icon-themes$/ ||
        $p_options->{'package_name'} =~ m/^OpenOffice_org-l10n-group1$/ ||
        $p_options->{'package_name'} =~ m/^OpenOffice_org-l10n-group2$/ ||
        $p_options->{'package_name'} =~ m/^OpenOffice_org-i18n-group1$/ ||
        $p_options->{'package_name'} =~ m/^OpenOffice_org-i18n-group2$/ ||
        $p_options->{'package_name'} =~ m/^OpenOffice_org-i18n$/) {
	$version_reg = '\%define\s*ooo_build_version\s*([\.\w]+)';
	# OOo_BUILD_VERSION is used on NLD9
	# $version_reg = '\%define\s*OOo_BUILD_VERSION\s*([\.\w]+)';
    } else {
	$version_reg = 'Version:\s*([\.\w]+)';
    }
    
    open (SPEC, "$p_options->{'package_source_path'}/$p_options->{'specfile'}") ||
	die "can't open \"$p_options->{'package_source_path'}/$p_options->{'specfile'}\" for reading: $!\n";

    while (my $line = <SPEC>) {
        chomp $line;
    
	if ($line =~ m/$version_reg/) {
	    $p_options->{'version'}="$1";
	}
    }
    close (SPEC);

    unless (defined $p_options->{'version'}) {
	show_error("Package version did not found in \"$p_options->{'package_source_path'}/$p_options->{'specfile'}\"");
    }
    return;
}

sub check_distro($)
{
    my ($p_options) = @_;
    
    # FIXME: We should check the architecture of the host
    unless (defined $p_options->{'distro'}) {
	show_warning("Warning: distro is not defined; Defaulting to i386!");
	$p_options->{'distro'} = "i386";
    }
}

sub check_for_noarch($)
{
    my ($p_options) = @_;
    my $result = 0;

    open (SPEC, "$p_options->{'package_source_path'}/$p_options->{'specfile'}") ||
	die "can't open \"$p_options->{'package_source_path'}/$p_options->{'specfile'}\" for reading: $!\n";

    while (my $line = <SPEC>) {
        chomp $line;

	if ($line =~ m/BuildArch\s*:\s*noarch/) {
	    $result = 1;
	    last;
	}
    }
    close (SPEC);
    
    return $result
}

sub set_archs($)
{
    my ($p_options) = @_;

    # architectrure is the last piece of the distro string
    $p_options->{'distro_arch'} = $p_options->{'distro'};
    $p_options->{'distro_arch'} =~ s/.*-//g;
    
    if (check_for_noarch($p_options)) {
	$p_options->{'rpm_arch'} = "noarch"
    } else {
	$p_options->{'rpm_arch'} = $p_options->{'distro_arch'};
    }
    $p_options->{'rpm_arch'} =~ s/i386/i586/;
}

sub set_status_file($)
{
    my ($p_options) = @_;

    unless (defined $p_options->{'status_file'}) {
	$p_options->{'status_file'} = "$p_options->{'package_source_path'}/../$p_options->{'buildroot_name'}.stat";
    }
    
    return;
}

sub set_rebuild_options($)
{
    my ($p_options) = @_;
    
    if (-r $p_options->{'status_file'}) {
	$p_options->{'remote_tempdir'} = read_item_from_stat("remote_tempdir", $p_options->{'status_file'}, 1);
	$p_options->{'remote_prefer_rpms'} = read_item_from_stat("remote_prefer_rpms", $p_options->{'status_file'}, 1);
	$p_options->{'replace_status_file'} = 1;
    }	
    $p_options->{'force'} = 1;
}

sub show_status($)
{
    my ($p_options) = @_;

    my $re_use = '';
    $re_use = " (re-use)" if (defined $p_options->{'re_using_remote_tempdir'});

    my $force = '';
    $force = " (force)" if (defined $p_options->{'force'});

    my $keep_remore_sources = '';
    $keep_remore_sources = " (keep)" if (defined $p_options->{'keep_remote_tempdir'});


    print ("\n");
    print ("Package name:     $p_options->{'package_name'}\n");
    print ("Package version:  $p_options->{'version'}\n\n");

    print ("Distro:           $p_options->{'distro'}\n");
    print ("Host:             $p_options->{'host'}\n\n");

    print ("Pkg. Sources:     $p_options->{'package_source_path'}\n");
    print ("Pkg Rmt. Sources: $p_options->{'package_remote_sources_path'}$re_use$keep_remore_sources\n\n");

    print ("BuildRoot:        $p_options->{'buildroot'}$force\n");
    print ("\n");

#    print ("package_sources_name = $p_options->{'package_source_name'}\n");
#    print ("Spec file:	     $p_options->{'specfile'}\n");
}

sub save_status($$)
{
    my ($p_options, $force) = @_;

    return unless (defined $p_options->{'status_file'});

    if (-e $p_options->{'status_file'}) {
	unless ((defined $p_options->{'replace_status_file'}) || $force ) {
	    show_error("Error: Status file \"$p_options->{'status_file'}\" already exists");
	}
    }

    open (STATE, '>', "$p_options->{'status_file'}") ||
	show_error("Can't open \"$p_options->{'status_file'}\" for writing: $!");

    print STATE "package_name = $p_options->{'package_name'}\n";
    print STATE "version = $p_options->{'version'}\n";
    print STATE "distro = $p_options->{'distro'}\n\n";
    print STATE "host = $p_options->{'host'}\n\n";

    print STATE "package_source_path = $p_options->{'package_source_path'}\n";
    print STATE "package_source_name = $p_options->{'package_source_name'}\n";
    print STATE "specfile = $p_options->{'specfile'}\n\n";

    print STATE "distro_arch = $p_options->{'distro_arch'}\n\n";
    print STATE "rpm_arch = $p_options->{'rpm_arch'}\n\n";

    print STATE "remote_tempdir = $p_options->{'remote_tempdir'}\n";
    print STATE "package_remote_sources_path = $p_options->{'package_remote_sources_path'}\n";
    print STATE "remote_prefer_rpms = $p_options->{'remote_prefer_rpms'}\n";

    print STATE "buildroot = $p_options->{'buildroot'}\n";
    print STATE "remote_rpms_path = $p_options->{'remote_rpms_path'}\n";
    print STATE "get_packages_path = $p_options->{'get_packages_path'}\n\n";

    print STATE "built = $p_options->{'built'}\n";
    print STATE "downloaded = $p_options->{'downloaded'}\n";

    close (STATE);
}

# FIXME: there should be another function to read the whole stat file if needed
sub read_item_from_stat($$$)
{
    my ($item_name, $status_file, $optional) = @_;
    my $item_value;

    unless (open (STATE, "$status_file")) {
	if ($optional) {
	    return $item_value;
	} else {
	    show_error("Can't open \"$status_file\" to read \"$item_name\": $!");
	}
    }
    
    while (my $line = <STATE>) {
        chomp $line;
	if ( $line =~ m/$item_name\s*=\s*(.*)\s?/ ) {
	    $item_value = "$1";
	    $item_value = undef if (length($item_value) == 0);
	}
    }
    
    close (STATE);

    unless ($optional || defined $item_value) {
	show_error("Error: $item_name entry not found in $status_file");
    }	
    
    return $item_value;
}

sub usage()
{
    print "This tool helps to build packages on remote machines. Unfortunately, it is\n" .
	  "SUSE specific.\n\n" .
    
          "Usage:\n".
	  "\tooo-build-release [--help] [--host=<host>] [--distro=<distro>]\n" .
	  "\t[--buildid=<id>] [--min] [--prefer-rpms=<dir>]\n" .
	  "\t[--icecream=<njobs>] [--debug=<opts>]\n" .
	  "\t[--rebuild[=<stat_file>]] [--force] \n" .
	  "\t[--ptf=<bugid>] [--security] [--buildroot=<name>]\n" .
	  "\t[--status-file=<stat_file>] [--replace-status-file=<stat_file>]\n" .
	  "\t[--get-status-file]\n" .
	  "\t[--prefer-rpms-from-build=<stat_file>]\n" .
	  "\t[--re-use-remote-prefer-rpms-from-build=<stat_file>]\n" .
	  "\t[--re-use-remote-sources-from-build=<stat_file>]\n" .
	  "\t[--do-not-update-remote-sources] [--keep-remote-tempdir]\n" .
	  "\t[--remove-remote-tempdir=<stat_file>][--no-final-message]\n" .
	
	  "Options:\n" .
	  "\t--help: prints this help\n" .
	  "\t--host: where to build\n" .
	  "\t--distro: for what distro build\n" .
	  "\t--prefer-rpms: use rpms from the given directory to install\n" .
	  "\t\tthe build-root\n" .
	  "\t--icecream: allow to use icecream with the specified number of\n" .
	  "\t\tparallel jobs\n" .
	  "\t--debug: also build the debug package; If <opts> is \"yes\",\n" .
	  "\t\tuse default settings for debugging. Otherwise append <opts>\n" .
	  "\t\tto \$RPM_OPT_FLAGS\n" .
	  "\t--rebuild: start the build again; re-use the remote sources copy;\n" .
	  "\t\tre-use the buildroot, ...\n" .
	  "\t--force: re-use remote buildroot if it exists\n" .
	  "\t--buildid: define extra id to do the \"same\" build in another\n" .
	  "\t\tbuildroot\n" .
	  "\t--min: affects the buildroot name only now\n" .
	  "\t--ptf: do PTF build for the given bugid\n" .
	  "\t--security: build security fix; defined special builroot number\n" .
	  "\t--buildroot: force another buildroot directory\n" .
	  "\t--status-file: where to store information about the current build;\n" .
	  "\t\tit can be reused for consequent builds\n" .
	  "\t--replace-status-file: the same like --status-file but it allows to\n" .
	  "\t\trewrite the older one\n" .
	  "\t--get-status-file: print the path to the status file; note that the\n" .
	  "\t\tdefault status file name is derived from other options, like\n" .
	  "\t\t--distro, --min\n" .
	  "\t--prefer-rpms-from-build: prefer_rpms produced by another build\n" .
	  "\t--re-use-remote-prefer-rpms-from-build: re-use the remote prefer\n" .
	  "\t\tRPMs directory\n" .
	  "\t--re-use-remote-sources-from-build: re-use an older remote source dir;\n" .
	  "\t\tit might speed up the source synchronization\n" .
	  "\t--do-not-update-remote-sources: skip the source synchronization at all\n" .
	  "\t--keep-remote-tempdir: do not remove the remote source dir after a\n" .
	  "\t\tsuccessful build\n" . 
	  "\t--remove-remote-tempdir: just remove the remote temporary directory\n" .
	  "\t\tfor the given status file and exit\n" .
	  "\t--no-final-message: do not show extra pop up window about about that\n" .
	  "\t\tbuild succeeded\n";

#	  "\t--debug=<opts>:\n" .
#	  "\t--prefer-rpms=:\n" .
#	  "\t--icecream=<number>=:\n" .
#	  "\t--extra-packs=<list of packs>=:\n" .	  
#	  "\t--no-lint:\n" .
#	  "\t--distros=<list of distros>:\n" .
#	  "\t--clean:\n" .
#	  "\t--icecream=<number>:\n" .
#	  "\t--ptf: release ptf-specific tarball for given bugzilla number\n";
}

my %options;

###################
# Arguments parsing
###################

for my $arg (@ARGV) {
    if ($arg eq '--help' || $arg eq '-h') {
	usage;
	exit 0;
    } elsif ($arg =~ m/--rebuild=?(.*)?/) {
	$options{'status_file'} = "$1" if (length($1));
	$options{'rebuild'} = 1;
    } elsif ($arg =~ m/--status-file=(.*)/) {
	$options{'status_file'} = "$1";
    } elsif ($arg =~ m/--get-status-file/) {
	$options{'get_status_file'} = 1;
    } elsif ($arg =~ m/--replace-status-file=(.*)/) {
	$options{'status_file'} = "$1";
	$options{'replace_status_file'} = 1;
    } elsif ($arg =~ m/--prefer-rpms-from-build=(.*)/) {
	$options{'local_prefer_rpms'} = read_item_from_stat("get_packages_path", "$1", 0);
	$options{'local_prefer_rpms'} .= "/devel";
    } elsif ($arg =~ m/--re-use-remote-prefer-rpms-from-build=(.*)/) {
	$options{'remote_prefer_rpms'} = read_item_from_stat("remote_prefer_rpms", "$1", 0);
    } elsif ($arg =~ m/--re-use-remote-sources-from-build=(.*)/) {
	$options{'remote_tempdir'} = read_item_from_stat("remote_tempdir", "$1", 0);
	$options{'re_using_remote_tempdir'} = 1;
    } elsif ($arg =~ m/--do-not-update-remote-sources/) {
	$options{'do_not_update_remote_sources'} = 1;
    } elsif ($arg =~ m/--keep-remote-tempdir/) {
	$options{'keep_remote_tempdir'} = 1;
    } elsif ($arg =~ m/--remove-remote-tempdir=(.*)/) {
	$options{'remote_tempdir'} = read_item_from_stat("remote_tempdir", "$1", 0);
	$options{'remove_remote_tempdir'} = 1;
    } elsif ($arg =~ m/--packages=(.*)/) {
	$options{'packages'} = "$1";
    } elsif ($arg =~ m/--devel-packages=(.*)/) {
	$options{'devel_packages'} = "$1";
    } elsif ($arg =~ m/--get-packages=(.*)/) {
	$options{'get_packages_path_prefix'} = "$1";
    } elsif ($arg =~ m/--buildid=(.*)/) {
	$options{'buildid'} = "$1";
    } elsif ($arg =~ m/--min/) {
	$options{'min'} = 1;
    } elsif ($arg =~ m/--ptf=(.*)/) {
	$options{'ptf'} = 1;
	$options{'bugid'} = "$1";
    } elsif ($arg =~ m/--security/) {
	$options{'security'} = 1;
    } elsif ($arg =~ m/--force/) {
	$options{'force'} = 1;
    } elsif ($arg =~ m/--no-final-message/) {
	$options{'no_final_message'} = 1;
    } elsif ($arg =~ m/--host=(.*)/) {
	$options{'host'} = "$1";
    } elsif ($arg =~ m/--distro=(.*)/) {
	$options{'distro'} = "$1";
    } elsif ($arg =~ m/--icecream=(.*)/) {
	$options{'icecream'} = 1;
	$options{'jobs'} = "$1";
    } elsif ($arg =~ m/--prefer-rpms=(.*)/) {
	$options{'local_prefer_rpms'} = "$1";
    } elsif ($arg =~ m/--debug=?(.*)/) {
	$options{'debug'} = "$1";
    } elsif ($arg =~ m/--buildroot=(.*)/) {
	$options{'buildroot'} = "$1";
    } else {
	if (! defined $options{'specfile_path'}) {
	    $options{'specfile_path'} = $arg;
	} else {
	    die "Too many arguments $arg\n";
	}
    }
}

if (defined $options{'remove_remote_tempdir'}) {
    remove_remote_tempdir(\%options);
    exit 0;
}

find_specfile(\%options);
set_package_name(\%options);
find_package_sources(\%options);
check_distro(\%options);
set_archs(\%options);
set_package_version(\%options);
set_packdir_names(\%options);
set_status_file(\%options);

if (defined $options{'get_status_file'}) {
    print "$options{'status_file'}\n";
    exit 0;
}

unless (defined $options{'force'}) {
    # will skip build and/or download when already done
    $options{'built'} = read_item_from_stat("built", "$options{'status_file'}", 1);
    $options{'downloaded'} = read_item_from_stat("downloaded", "$options{'status_file'}", 1);
}

set_rebuild_options(\%options) if (defined $options{'rebuild'});

check_free_space($options{'host'}, "/abuild", $critical_free_space_limit_abuild);

check_buildroot(\%options);
set_rpms_paths(\%options);
create_remote_tempdir(\%options);
set_package_remote_sources_path(\%options);
set_remote_prefer_rpms_path(\%options);

save_status(\%options, 0);

show_status(\%options);
print ("Waiting 5 seconds...\n");
# do not delay already finished build
sleep 5 unless (defined $options{'built'} && "$options{'built'}" eq "yes");

# always upload sources, they might be necessary to rebuild the other spec files
upload_sources(\%options);
# update prefer rpms only when we will build the package
upload_prefer_rpms(\%options) unless (defined $options{'built'} && "$options{'built'}" eq "yes");

abuild_package(\%options) unless (defined $options{'built'} && "$options{'built'}" eq "yes");

get_packages(\%options) unless (defined $options{'downloaded'} && $options{'downloaded'} eq "yes");

remove_remote_tempdir(\%options);

show_msg("Abuild succeeded at $options{'host'}:$options{'buildroot'}\n") unless (defined $options{'no_final_message'});
