#!/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 File::Temp;
use Data::Dumper;

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

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

#
# FIXME: what about /root/.curlrc for proxy settings?
#
if(!SMT::Utils::dropPrivileges())
{
    print STDERR __("Unable to drop privileges. Abort!\n");
    exit 1;
}

my $debug   = 0;
my $vblevel  = LOG_ERROR|LOG_WARN|LOG_INFO1;
my $help    = 0;
my $random  = 0;
my $reseterror = 0;
my $logfile = "/dev/null";
my $mail     = 0;
my $mailtempfile = undef;

Getopt::Long::Configure( 'no_auto_abbrev');
my $optres = GetOptions ("debug|d"     => \$debug,
                         "verboselevel|v=i" => \$vblevel,
                         "logfile|L=s" => \$logfile,
                         "randomStart|r" => \$random,
                         "reseterror"  => \$reseterror,
                         "mail|m"       => \$mail,
                         "help|h"      => \$help
                        );

if($help || !$optres)
{
    print basename($0) . " [--reseterror] [--debug] [--logfile file] [--mail]\n\n";
    print __("Register all clients at SCC which are currently not registered\n");
    print __("or which data changed since the last registration.\n");
    print "\n";
    print __("Options:\n");
    print "--reseterror            ".__("reset the SCC registration error flag and try to submit failed registrations again.\n");
    print "--mail -m               ".__("Send output as e-mail to the administrators defined in reportEmail in smt.conf.\n");
    print "                        ".__("The output on stdout and stderr will be suppressed.\n");
    print "--debug -d              ".__("enable debug mode\n");
    print "--verboselevel -v level " . __("set the verbose level\n");
    print "--logfile -L file       ".__("Path to logfile\n");
    exit 0;
}

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

if($mail)
{
    my $dir = File::Temp::tempdir("smt-XXXXXXXX", CLEANUP => 1, TMPDIR => 1);
    $mailtempfile = "$dir/mail";
    open(MAILTEMPFILE, "> $mailtempfile") or die "Cannot open file:$!";
    open(STDOUT, ">& MAILTEMPFILE") or die "Cannot dup:$!";
    open(STDERR, ">& MAILTEMPFILE") or die "Cannot dup:$!";
    select STDERR; $| = 1;      # make unbuffered
    select STDOUT; $| = 1;      # make unbuffered
    select MAILTEMPFILE; $| = 1;        # make unbuffered
}

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

# open the logfile

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

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


# check if we are allowed to register clients at SCC

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-register", 1, $LOG, $vblevel );
}

my $allowRegister = $cfg->val("LOCAL", "forwardRegistration");
if(!(defined $allowRegister && $allowRegister eq "true"))
{
    SMT::Utils::unLockAndExit( "smt-register", 0, $LOG, $vblevel );
}
my $nccEmail = $cfg->val("LOCAL", "nccEmail");

my $sleeptime = 0;

$sleeptime = $cfg->val("LOCAL", "rndRegister", "0") if($random);

my $dbh = undef;

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

if(!$dbh)
{
    SMT::Utils::printLog($LOG, $vblevel, LOG_ERROR, __("Cannot connect to database"));
    SMT::Utils::unLockAndExit( "smt-register", 1, $LOG, $vblevel );
}

my $exitcode = 0;
eval
{
    if($reseterror)
    {
        my $res = $dbh->do("Update Registration SET NCCREGERROR=0");
        SMT::Utils::printLog($LOG, $vblevel, LOG_DEBUG, "Reset NCC Registration Errors. Result: $res");
    }
    my $api = $cfg->val("NU", "ApiType", "NCC");
    if( $api eq "NCC")
    {
        # TODO
        SMT::Utils::printLog($LOG, $vblevel, LOG_ERROR, __("NCC is not supported by this version of SMT"));
        $exitcode = 1;
    }
    elsif ($api eq 'SCC')
    {
        my $sccreg = SMT::SCCSync->new(vblevel   => $vblevel,
                                       useragent => $useragent,
                                       log       => $LOG,
                                       dbh       => $dbh,
                                       nccemail  => $nccEmail);
        my $err = $sccreg->register_systems($sleeptime);
        if($err != 0)
        {
            $exitcode = 1;
        }
    }
    else {
        MT::Utils::printLog($LOG, $vblevel, LOG_ERROR, __("Unknown API $api"));
        $exitcode = 1;
    }
};

if($@)
{
    $exitcode = 1;
}

if($mail)
{
    close (STDERR);
    close (STDOUT);
    close (MAILTEMPFILE);
    my $body = "";

    # we want to send only a mail, if there is something to send.
    if( -s $mailtempfile )
    {
        open(MAIL, "< $mailtempfile") and do
        {
            while(<MAIL>)
            {
                $body .= $_;
            }
            close MAIL;
        };
        my $datestring = POSIX::strftime("%Y-%m-%d %H:%M", localtime);
        my $subject = sprintf("SMT Registration Report $datestring (%s) -- Registration %s",
                              SMT::Utils::getFQDN(), (($exitcode > 0)?"failed":"successful"));

        SMT::Utils::sendMailToAdmins($subject, $body);
    }
}

SMT::Utils::unLockAndExit( "smt-register", $exitcode, $LOG, $vblevel );


#
# Manpage
#

=head1 NAME

smt register

=head1 SYNOPSIS

smt [help|--help|-h] register

smt register [--reseterror] [--debug] [--logfile file] [--mail]

=head1 DESCRIPTION

smt register registers all clients at SCC which are currently not registered
or which data changed since the last registration. It skips all clients which
registration failed the last time unless the B<--reseterror> parameter is used.


=head1 OPTIONS

=over

=item --reseterror

Reset the error flags and register the clients again.

=item --mail -m

Send output as e-mail to the administrators defined in reportEmail in smt.conf .
The output on stdout and stderr will be suppressed in this mode.

=item --debug

Enable debug mode.

=item --verboselevel -v <level>

Set the output verbose level. The following categories exists.
These categories can be bitwise-or'd to use as verbose level.

=over 4

=item error messages

Value: 0x0001 == 1

=item warning messages

Value: 0x0002 == 2

=item info messages 1

Value: 0x0004 == 4

=item info messages 2

Value: 0x0008 == 8

=item debug messages 1

Value: 0x0010 == 16

=item debug messages 2

Value: 0x0020 == 32

=item debug messages 3

Value: 0x0040 == 64

=back

The default verbose level is 7 (error, warning and info1 messages).
B<--debug> set the verbose level to 63.

=item --logfile -L  <file>

Write log messages to B<file>.

=item --help -h

Show a help message.

=back

=head1 EXAMPLES

Register all clients which are currently not registered or whose
registration data was updated since the last registration.

 smt register

with writing to a logfile

 smt register --logfile /var/log/smt-register.log

enable debug mode

 smt register --debug

reset the error flag and register all clients which need a new registration

 smt register --reseterror -L /var/log/smt-register.log


=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


