#!/usr/bin/perl

###############################################################################
## Copyright (c) 2007-2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
###############################################################################

use strict;
use warnings;
use FindBin;
BEGIN { unshift @INC, "$FindBin::Bin/../www/perl-lib" }

use SMT::Utils;
use SMT::SCCSync;
use Getopt::Long;
use File::Basename;
use DateTime;
use Data::Dumper;

use Locale::gettext ();
use POSIX ();     # Needed for setlocale()

POSIX::setlocale(&POSIX::LC_MESSAGES, "");

if(!SMT::Utils::dropPrivileges())
{
    print STDERR __("Unable to drop privileges. Abort!\n");
    exit 1;
}

my $vblevel  = LOG_ERROR|LOG_WARN|LOG_INFO1|LOG_INFO2;
my $debug = 0;
my $help  = 0;
my $logfile = "/dev/null";
my $lastcontact;

my @guids = ();

my $optres = GetOptions ("guid|g=s"    => \@guids,
                         "logfile|L=s" => \$logfile,
                         "debug|d"     => \$debug,
                         "verboselevel|v=i" => \$vblevel,
                         "help|h"      => \$help,
                         "older-than=s"  => \$lastcontact
                        );

if($help || !$optres)
{
    print basename($0) . __(" [OPTIONS]\n");
    print __("Delete one or more registration from SCC and SMT\n");
    print "\n";
    print __("Options:\n");
    print "  --guid (-g)            : " . __("Unique ID of the client which should be deleted.\n");
    print "                           " . __("This option can be used multiple times.\n");
    print "  --debug (-d)           : " . __("enable debug mode\n");
    print "  --logfile (-L) <file>  : " . __("Path to logfile")."\n";
    print "  --older-than           : " . __("Limit time or delta from now to delete registrations older than this limit.\n");
    exit 0;
}

$vblevel = LOG_ERROR|LOG_WARN|LOG_INFO1|LOG_INFO2|LOG_DEBUG|LOG_DEBUG2 if($debug);

if((@guids == 0) && (!$lastcontact))
{
    print STDERR __("No Unique ID or date limit provided.\n");
    exit 1;
}

# open the logfile
my $LOG = SMT::Utils::openLog($logfile);

my $limitdate;
if ($lastcontact)
{
    my $timezone = 'UTC';
    eval
    {
        my $timezone = DateTime::TimeZone->new( name => 'local' );
    };
    if($@)
    {
        SMT::Utils::printLog($LOG, $vblevel, LOG_INFO1, __('Unable to determine local timezone, using UTC'));
    }
    my $now = DateTime->now( time_zone => $timezone);
    if ($lastcontact =~ /\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/)
    {
        $limitdate = $lastcontact;
    }
    elsif ($lastcontact =~ /\d*m/) {
        chop $lastcontact;
        my $removetargetdate = $now->subtract( months => $lastcontact );
        my $date = $now->ymd('-');
        my $time = $now->hms(':');
        $limitdate = "$date $time";
    }
    elsif ($lastcontact =~ /\d*d/) {
        chop $lastcontact;
        my $removetargetdate = $now->subtract( days => $lastcontact );
        my $date = $now->ymd('-');
        my $time = $now->hms(':');
        $limitdate = "$date $time";
    }
    else
    {
        print STDERR __("Unsupported argument format: $lastcontact. Must be one of 'YYYY-MM-DD hh:mm:ss', 'd*m', or 'd*d'.\n");
        exit 1;
    }
}

if(!SMT::Utils::openLock("smt-delete-registration"))
{
    print __("Delete registration process is still running.\n");
    exit 0;
}

if(!SMT::Utils::openLock('smt-sibling-sync'))
{
    print __("Sibling sync is running cannot delete registrations.\n");
    SMT::Utils::unLockAndExit( "smt-delete-registration", 0, $LOG, $vblevel );
}

my $useragent = SMT::Utils::createUserAgent('log' => $LOG, 'vblevel' => $vblevel);
$useragent->protocols_allowed( [ 'https' ] );

my $cfg = undef;

eval
{
    $cfg = SMT::Utils::getSMTConfig();
};
if($@ || !defined $cfg)
{
    SMT::Utils::printLog($LOG, $vblevel, LOG_ERROR, sprintf(__("Cannot read the SMT configuration file: %s"), $@));
    SMT::Utils::unLockAndExit( "smt-delete-registration", 1, $LOG, $vblevel );
}

my $dbh = undef;

$dbh = SMT::Utils::db_connect();

if(!$dbh)
{
    if(!SMT::Utils::unLock("smt-delete-registration"))
    {
        print STDERR __("Cannot remove lockfile.\n");
    }
    die __("Cannot connect to database");
}

if ($limitdate) {
    my $statement = 'SELECT GUID from Clients WHERE LASTCONTACT < ';
    $statement .= $dbh->quote($limitdate);
    my $clientguids = $dbh->selectcol_arrayref($statement);
    push @guids, @{$clientguids};
}

eval
{
    my $err = 1;
    if($cfg->val("NU", "ApiType", "NCC") eq "NCC")
    {
        SMT::Utils::printLog($LOG, $vblevel, LOG_ERROR, __("NCC is not supported by this version of SMT"));
    }
    else
    {
        my $sccreg = SMT::SCCSync->new(vblevel   => $vblevel,
                                       useragent => $useragent,
                                       log       => $LOG,
                                       dbh       => $dbh);
        $err = $sccreg->delete_systems(@guids);
    }
    if($err != 0)
    {
        SMT::Utils::unLockAndExit( "smt-delete-registration", 1, $LOG, $vblevel );
    }
};
if($@)
{
    print STDERR __("Failed to delete registration for id $@\n");
    SMT::Utils::unLockAndExit( "smt-delete-registration", 1, $LOG, $vblevel );
}

SMT::Utils::unLockAndExit( "smt-sibling-sync", 0, $LOG, $vblevel );
SMT::Utils::unLockAndExit( "smt-delete-registration", 0, $LOG, $vblevel );


#
# Manpage
#

=head1 NAME

smt delete-registration

=head1 SYNOPSIS

smt [help|--help|-h] delete-registration

smt delete-registration --guid|-g id1 [--guid|-g id2] ...

smt delete-registration --debug --guid id1

=head1 DESCRIPTION

I<smt delete-registration> deletes one or more registrations from SMT and SCC. It will deregister machines from the system.

=head1 OPTIONS

=head2 MACHINE GUID

=over

=item --guid|-g id

Deletes the machine with guid B<id> from the system. This parameter can be used multiple times.

=item --older-than

Deletes all machines with a "Last Contact" date that is older than the given date-time value or the given delta in months or days. Accepted formats are:

=over

=item C<YYYY-MM-DD hh:mm:ss>

The date time format as it is recorded in the database, for example "2014-10-09 09:30:00" would delete all machines that have not visisted the SMT server since October 9, 2014 at 9:30 in the morning.

=item C<d*m>

The time delta in months where "d*" may be any number of digits. For example a value of "18m" will caclculate the limit time to be 18 months prior to now and will delete all the machines that have not visisted the SMT server since the calculated limit time.

=item C<d*d>

The time delta in days where "d*" may be any number of digits. For example a value of "25d" will caclculate the limit time to be 25 days prior to now and will delete all the machines that have not visisted the SMT server since the calculated limit time.

=back

All calculations or the absolute date-time setting provided are considered to be in the SMT servers time zone setting.

=back

=head2 DEBUG

=over

=item --debug|-d

Enable debug mode for verbose logging.

=item --logfile|-L file

Write log messages to B<file>.

=back


=head1 AUTHORS and CONTRIBUTORS

Duncan Mac-Vicar Prett, Lukas Ocilka, Jens Daniel Schmidt, Michael Calmer

=head1 LICENSE

Copyright (c) 2007-2012 SUSE LINUX Products GmbH, Nuernberg, Germany.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 675 Mass
Ave, Cambridge, MA 02139, USA.

=cut

