#!/usr/bin/perl

use strict;
use warnings FATAL => 'all';

use Getopt::Long ();
use Frontier::Client;

my $idle_time;
my ($host, $username) = ( 'localhost', 'admin' );
my $passwd;
my $force;

my $usage = "Usage: $0 --idle=<idletime[w|d|h|m]> [--host=<host>] [--username=<username>] [--password=<password>] [--force]\n";
Getopt::Long::GetOptions(
	'idle=s' => \$idle_time,
	'host=s' => \$host,
	'username=s' => \$username,
	'password=s' => \$passwd,
	'force' => \$force,
) or die $usage;

if (not defined $idle_time) {
	die "Need --idle parameter\n";
}

if (not defined $passwd) {
        my $passwdfile = "/etc/rhn/$username-password";
        open PASSWD, $passwdfile or die "Error reading password file [$passwdfile]: $!\n";
        $passwd = <PASSWD>;
        chomp $passwd;
        close PASSWD;
}

my ($t, $w) = ($idle_time =~ /^(\d+)(\D)$/);

if (not defined $w) {
	$t = $idle_time;
	$w = 'd';
}
if ($w eq 'm') { $idle_time = $t * 60; }
elsif ($w eq 'h') { $idle_time = $t * 60 * 60; }
elsif ($w eq 'd') { $idle_time = $t * 60 * 60 * 24; }
elsif ($w eq 'w') { $idle_time = $t * 60 * 60 * 24 * 7; }
else {
	die "Unknown idle parameter [$idle_time]\n";
}

my $not_before = time - $idle_time;
my ($sec, $min, $h, $d, $m, $y) = localtime($not_before);
my $cutoff = sprintf '%04d%02d%02dT%02d:%02d:%02d',
				$y + 1900,$m + 1, $d, $h, $min, $sec;
print "Lookup on [$host] systems with last checkin before [$cutoff]\n";

my $client = new Frontier::Client(url => "http://$host/rpc/api", debug=>0);
my $session = $client->call('auth.login', $username, $passwd)
	or die "Failed to login to [$host]\n";

my $systems = $client->call('system.list_user_systems', $session);
$systems = [
	sort { $a->{last_checkin} cmp $b->{last_checkin} }
	map { if (ref $_->{last_checkin}) {
		$_->{last_checkin} = $_->{last_checkin}->value
	} else {
		$_->{last_checkin} =~ s/-//g;
	}; $_;} @$systems
];

my $delete = 0;
my $total = @$systems;
$cutoff =~ s/\D//g;
for (my $i = 0; $i < @$systems; $i++) {
	my $sys = $systems->[$i];
	my $sys_date = $sys->{last_checkin};
	$sys_date =~ s/\D//g;
	if (length($sys_date) == 8) {
		$sys_date .= '235959';
	}
	print "System [$sys->{name}] id [$sys->{id}] last checking [$sys->{last_checkin}] ";
	if ($sys_date lt $cutoff) {
		print " -> delete";
		$delete ++;
	} else {
		splice @$systems, $i, 1;
		$i--;
	}
	print "\n";
}
if (not $delete ) {
	print "Total systems [$total], none idle\n";
	exit;
}
if (not $force) {
	print "Total systems [$total], would delete [$delete]\n";
	exit;
}

print "Total systems [$total], will delete [$delete]\n";

if (not $client->call('system.delete_systems', $session, [map $_->{id}, @$systems ])) {
	print "Error deleting system [sys->{id}]\n";
} else {
	print "All systems deleted\n";
}

=pod

=head1 NAME

delete-old-systems-interactive - delete inactive systems from Spacewalk server.

=head1 SYNOPSIS

delete-old-systems-interactive [OPTIONS] --idle time_delta

=head1 DESCRIPTION

delete-old-systems-interactive - will use Spacewalk API to determine when each registred system checked in
last time and optionaly will delete systems which have been inactive for time_delta.

This script will list all registred systems and their last check in. And will if none system is idle more
then time_delta, it will write summary:

 Total systems [127], none idle

If some systems are idle more then time_delta, you will get summary like:

 Total systems [127], would delete [51]

None system is deleted by default, unless you specify --force option.

=head1 OPTIONS

--idle time_delta
        Search for system, which are inactive for more then time_delta.
        If only number is specified, it is interpreted as days. You can use suffixes m (for minutes),
        h (hours), d (days) and w (weeks). E.g. "--idle 10" and "--idle 10d" is the same and means
        ten days, "--idle 2w" means two weeks.

--host host
        Hostname of you Spacewalk server. If not set, localhost is used by default.

--username login
        Your username. By default "admin".

--password pass
        Your password. If not specified on command line, then it is read from /etc/rhn/$username-password

--force
        If specified, then idle systems are deleted.

=head1 EXAMPLES

  delete-old-systems-interactive --server=spacewalk.com --idle 30d

=head1 AUTHOR

Miroslav Suchy <msuchy@redhat.com>,
Jan Pazdziora <jpazdziora@redhat.com>

=head1 COPYRIGHT AND LICENSE

Copyright (c) 2009--2012 Red Hat, Inc.
Released under GNU General Public License, version 2 (GPLv2).

=cut

