package LATMOS::Accounts::Task;

use strict;
use warnings;
use LATMOS::Accounts::Log;

=head1 NAME

    LATMOS::Accounts::Task

=head1 DESCRIPTION

Parent class for regular task run by L<la-sync-manager>

=head1 FUNCTIONS

=head2 new($module, %options)

Instanciate a new task of type C<$module>

The module must provide a C<_new()> function.

=cut

sub new {
    my ($class, $module, %options) = @_;
    my $pclass = ucfirst(lc($module));
    my $me = __PACKAGE__;
    eval "require ${me}::$pclass;";
    if ($@) { return } # error message ?
    return "${me}::$pclass"->_new(%options);
}

sub _new {
    my ($class, %options) = @_;
    bless { %options }, $class;
}

=head2 config($value, $default)

Return config value for the module

=cut

sub config {
    my ($self, $value, $default) = @_;

    return $self->{syncm}->ini->val($self->{name}, $value, $default)
}

=head2 order

Return the priority for the module: 0, 1 or 2 (0 = first)

=cut

sub order { 1 }

=head2 init

Call at task startup, can be overload

=cut

sub init {
    return 1;
}

=head2 needupd($baserev, $syncm)

This function is to call to check if the module have to run or not.

C<$baserev> is the current base revision en C<$syncm> the revision when
la-sync-manager was run.

By default return true only if base has changed, overload for different
behavior.

=cut

sub needupd {
    my ($self, $lastrev, $currentrev) = @_;

    la_log LA_DEBUG, "Comparing db: %d <=> %d", $currentrev, $lastrev;
    if ($currentrev > $lastrev) {
        return 1;
    } else {
        la_log LA_DEBUG, "No change in DB, doing nothing";
        return;
    }
}

=head2 runDelay

Return the minumum of second to wait to have the module running again.

Return 0 but can be override by Task module.

=cut

sub runDelay { 0; }

=head2 waitDelay

Return the number of second to wait before next run even there is a change in database.

Return 0 but can be override by Task module.

=cut

sub waitDelay { 0; }

=head2 needToBeRun

Return TRUE is the module has to be run or not.

=cut

sub needToBeRun {
    my ($self, $Sync, $module) = @_;

    my ($lastrev, $lastRunTime) = $Sync->get_last_rev($module);

    my $currentrev = $Sync->dbrev;
    my $currentTime = time;
    
    if ($currentTime < $lastRunTime + $self->waitDelay) {
        la_log LA_DEBUG, "Too early to run this module now";
        return 0;
    }

    if ($self->needupd($lastrev, $currentrev, $Sync)) {
        return 1;
    } else {
        la_log LA_DEBUG, "No change on main base, cheking delay";
    }


    if (my $delay = $self->runDelay) {
        if ($currentTime >= $lastRunTime + $self->runDelay) {
            return 1;
        } else {
            la_log LA_DEBUG, "Too short delay to run self, waiting";
        }
    }

    return 0;
}

=head2 run

Must be provided by module, do the desired work.

=cut

sub run {
    return 1;
}

=head2 post

Call after C<run()>

=cut

sub post {
}

=head2 reset_savepoint

Reset the savepoint to 0 to force the module to be run again

=cut

sub reset_savepoint {
    return 1;
}

1;

__END__

=head1 SEE ALSO

L<LATMOS::Accounts::SyncManager>

=head1 AUTHOR

Thauvin Olivier, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2009, 2010, 2011, 2012 by Thauvin Olivier

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.10.0 or,
at your option, any later version of Perl 5 you may have available.

=cut
