# +==========================================================================+
# || CipUX::Object::Action::Attribute::List                                 ||
# ||                                                                        ||
# || CipUX Object Layer Class                                               ||
# ||                                                                        ||
# || Copyright (C) 2007 - 2009 by Christian Kuelker. All rights reserved!   ||
# ||                                                                        ||
# || License: GNU GPL version 2 or any later version.                       ||
# ||                                                                        ||
# +==========================================================================+
# $Id: List.pm 5011 2010-07-30 23:31:16Z christian-guest $
# $Revision: 5011 $
# $HeadURL$
# $Date: 2010-07-31 01:31:16 +0200 (Sat, 31 Jul 2010) $
# $Source$

package CipUX::Object::Action::Attribute::List;

use 5.008001;
use strict;
use warnings;
use utf8;

use Carp;
use Class::Std;
use CipUX::Storage;
use Data::Dumper;
use Log::Log4perl qw(:easy);
use Pod::Usage;
use Readonly;

use base qw(CipUX::Object::Action);

{    # BEGIN CLASS

    use version; our $VERSION = qv('3.4.0.5');
    use re 'taint';    # Keep data captured by parens tainted
    delete @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)};    # Make %ENV safe

    # +======================================================================+
    # || CONSTANTS                                                          ||
    # +======================================================================+
    Readonly::Scalar my $EMPTY_STRING => q{};

    # +======================================================================+
    # || OBJECT                                                             ||
    # +======================================================================+

    #my %cfg_of :ATTR( init_arg => 'cfg'); # store conif file name

    # +======================================================================+
    # || GLOBAL VARS                                                        ||
    # +======================================================================+


    # +======================================================================+
    # || object                                                             ||
    # +======================================================================+

    # this is the entry point
    # same as: list_all_attribute_action
    sub list_object_attribute_action {

        # +------------------------------------------------------------------+
        # | API
        my ( $self, $arg_r ) = @_;

        my $action
            = exists $arg_r->{action}
            ? $self->l( $arg_r->{action} )
            : $self->perr('action');

        my $type
            = exists $arg_r->{type}
            ? $self->l( $arg_r->{type} )
            : $self->perr('type');

        # source here even if we source later for single debug handling
        # these are the given (CLI) values
        my %tmp    = ();
        my $tmp_hr = \%tmp;

        my $attr_hr
            = exists $arg_r->{attr_hr}
            ? $self->h( $arg_r->{attr_hr} )
            : $tmp_hr;

        # +------------------------------------------------------------------+
        # | prepare
        my $logger = get_logger(__PACKAGE__);
        $logger->debug('BEGIN');

        # debug API 1
        $logger->debug( 'action: ', $action );
        $logger->debug( 'type: ',   $type );

     # TODO: test this output
     #$logger->debug( 'attr_hr: ', { filter => &Dumper, value => $attr_hr } );

        # list object types and check it
        my $type_ar = $self->list_type();
        my %type    = ();
        foreach my $t ( @{$type_ar} ) {
            $type{$t} = 1;
            $logger->debug( 'found type: ', $t );
        }

        if ( not defined $type{$type} ) {
            $self->exc( { msg => 'unknown type', value => $type } );
        }

        $logger->debug( 'ACTION:: ', $action );

        # API 2
        my $object = undef;
        if ( $action eq 'list_object_attribute_action' ) {

            $object
                = exists $arg_r->{object}
                ? $self->l( $arg_r->{object} )
                : $self->perr('object');

            my $msg = 'Parameter "object" is not defined in';
            if ( not defined $object ) {
                $self->exc( { msg => $msg, value => $action } );
            }
            $msg = 'Parameter "object" is empty in';
            $msg .= ' list_object_attribute_action';
            if ( $object eq $EMPTY_STRING ) {
                $self->exc( { msg => $msg, value => $action } );
            }

        }
        my $scope
            = exists $arg_r->{scope}
            ? $self->l( $arg_r->{scope} )
            : $self->perr('scope');

        my $filter_hr
            = exists $arg_r->{filter_hr}
            ? $self->h( $arg_r->{filter_hr} )
            : $self->perr('filter_hr');

        my $target_hr
            = exists $arg_r->{target_hr}
            ? $self->h( $arg_r->{target_hr} )
            : $self->perr('target_hr');

        # debug API 2
        $logger->debug( 'object: ', $object );
        $logger->debug( 'scope: ',  $scope );

        my $cfg_coupling_hr = $self->get_coupling_cfg();
        my $v_hr            = $cfg_coupling_hr->{$type};

        # create hash ref
        my $c_hr = {};

        #my $object = $v_hr->{object_attr};
        #my $object = $v_hr->{object_attr};
        my $value_hr = $EMPTY_STRING;

        # for every object in 'order': cipux_share_object, ...
        foreach my $o ( @{ $v_hr->{order} } ) {
            $logger->debug( 'object to list: ', $o );

            # additional filter
            my $filter = $EMPTY_STRING;

            # &(cn=class84)
            # (objectClass=cipuxAccount)
            # (cipuxIsShare=TRUE)
            # (cipuxRole=course)
            if ( defined $filter_hr->{$o} ) {
                foreach my $key ( keys %{ $filter_hr->{$o} } ) {
                    my $value = $filter_hr->{$o}->{$key};
                    $filter .= "($key=$value)";
                    $logger->debug( 'add filter: ', $filter );
                }
            }

            # attributes to query
            my @attr = ();
            foreach my $attr ( sort keys %{ $target_hr->{$o} } ) {
                push @attr, $attr;
            }

            # only query objects containing the attribute
            # ex.: cipux_course_share *.group = yes, *.user = no
            next if not scalar @attr;

            # my $object_type_name = $cfg_coupling_hr->{$type};

            my $ldap = CipUX::Storage->new();
            $value_hr = $ldap->get_value(
                {
                    type    => $o,
                    scope   => $scope,
                    obj     => $object,
                    filter  => $filter,
                    attr_ar => \@attr
                }
            );

        }

        return $value_hr;
    }

}    # END INSIDE-OUT CLASS

1;

__END__

=pod

=head1 NAME

CipUX::Object::Action::Attribute::List - list object attribute actions

=head1 VERSION

version 3.4.0.5

=head1 SYNOPSIS

  use CipUX::Object::Action::Attribute::List

=head1 DESCRIPTION

Provides the functions cipux_object_create and cipux_object_destroy
as well as some auto-calculated values for example for userPassword.

=head1 SUBROUTINES/METHODS

The following functions will be exported by CipUX::Object.

=head2 list_object_attribute_action

TODO

=head1 DIAGNOSTICS

TODO

=head1 CONFIGURATION AND ENVIRONMENT

TODO

=head1 DEPENDENCIES

Carp
Class:Std
CipUX
CipUX::Storage
Pod::Usage
Date::Manip



=head1 INCOMPATIBILITIES

Not known.


=head1 BUGS AND LIMITATIONS

Not known.


=head1 SEE ALSO

See the CipUX web page and the manual at L<http://www.cipux.org>

See the mailing list L<http://sympa.cipworx.org/wws/info/cipux-devel>

=head1 AUTHOR

Christian Kuelker  E<lt>christian.kuelker@cipworx.orgE<gt>

=head1 LICENSE AND COPYRIGHT

Copyright (C) 2007 - 2009 by Christian Kuelker

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, 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA

=cut

