package LISM::Handler::Check;

use strict;
use base qw(LISM::Handler);
use POSIX qw(strftime);
use Data::Dumper;

=head1 NAME

LISM::Handler::Check - Handler to set value

=head1 DESCRIPTION

This class implements the L<LISM::Hanlder> interface to set value.

=head1 METHODS

=pod

=head2 getOrder

Get order to do handler.

=cut

sub getOrder
{
    return 'sync';
}

=head2 post_search($entriesp)

Check search results.

=cut


sub post_search
{
    my $self = shift;
    my ($entriesp) = @_;
    my $conf = $self->{_config};
    my $file = $conf->{file}[0];

    if (!open(FILE, ">> $file")) {
        $self->log(level => 'err', message => "Can't open $file");
        return -1;
    }

    foreach my $rule (@{$conf->{check}}) {
        my $timestamp = strftime("%Y%m%d%H%M%S", localtime(time));
        for (my $i = 0; $i < @{$entriesp}; $i++) {
            my $entryStr = ${$entriesp}[$i];
            my ($dn) = ($entryStr =~ /^dn: (.*)\n/);
            if (defined($rule->{dn}) && $dn !~ /$rule->{dn}/i) {
                next;
            }
            if (defined($rule->{filter}) && !LISM::Storage->parseFilter($rule->{filterobj}, $entryStr)) {
                next;
            }
            foreach my $attr (keys %{$rule->{attr}}) {
                my $cattr = $rule->{attr}{$attr};
                my @values = ($entryStr =~ /^$attr: (.+)$/mi);
                if (defined($cattr->{required}) && $cattr->{required}[0] eq 'on' && !@values) {
                    print FILE "$timestamp: $attr in $dn is required value\n";
                }
                foreach my $value (@values) {
                    if (defined($cattr->{minlen}) && length($value) < $cattr->{minlen}[0]) {
                        print FILE "$timestamp: $attr($value) in $dn is too short\n";
                    }
                    if (defined($cattr->{maxlen}) && length($value) > $cattr->{maxlen}[0]) {
                        print FILE "$timestamp: $attr($value) in $dn is too long\n";
                    }
                    if (defined($cattr->{regexp}) && $value !~ /$cattr->{regexp}[0]/) {
                        print FILE "$timestamp: $attr($value) in $dn is invalid: regular expression is $cattr->{regexp}[0]\n";
                    }
                    if (defined($cattr->{function})) {
                        my $rc = 0;
                        eval "\$rc = $cattr->{function}[0](\$entryStr, \$attr)";
                        if (!$rc) {
                            print FILE "$timestamp: $attr($value) in $dn is invalid: function is $cattr->{function}[0]\n";
                        }
                    }
                }
            }
        }
    }
    close(FILE);

    return 0;
}

sub _checkConfig
{
    my $self = shift;
    my $conf = $self->{_config};
    my $rc = 0;

    if ($rc = $self->SUPER::_checkConfig()) {
        return $rc;
    }

    if (defined($conf->{libload})) {
        foreach my $lib (@{$conf->{libload}}) {
            eval "do \'$lib\'";
            if ($@) {
                $self->log(level => 'alert', message => "check do require $lib: $@");
                return 1;
            }
        }
    }

    if (defined($conf->{check})) {
        foreach my $rule (@{$conf->{check}}) {
            if (defined($rule->{filter})) {
                $rule->{filterobj} = Net::LDAP::Filter->new($rule->{filter});
            }
        }
    }

    return $rc;
}

=head1 SEE ALSO

L<LISM>,
L<LISM::Handler>

=head1 AUTHOR

Kaoru Sekiguchi, <sekiguchi.kaoru@secioss.co.jp>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2006 by Kaoru Sekiguchi

This library is free software; you can redistribute it and/or modify
it under the GNU LGPL.

=cut

1;
