package tests::GroupTest;

use strict;

use base qw/ Lire::Test::TestCase tests::TestStoreFixture /;

use Lire::ReportSpec;
use Lire::Group;
use Lire::GroupField;
use Lire::Param;
use Lire::DlfQuery;
use Lire::Report::Group;
use tests::MockAggregate;

sub new {
    my $self = shift()->SUPER::new( @_ );

    $self->init();

    $self;
}

sub set_up {
    my $self = shift->SUPER::set_up();

    $self->set_up_test_schema();
    $self->set_up_nested_spec();

    return;
}

sub tear_down {
    my $self = $_[0];

    $self->SUPER::tear_down();

    return;
}

sub set_up_nested_spec {
    my $self = $_[0];

    $self->{'spec'} = new Lire::ReportSpec();
    $self->{'spec'}->superservice( 'test' );
    $self->{'spec'}->param( 'limit', new Lire::Param( 'name' => 'limit',
                                                      'type' => 'int',
                                                      'default' => 2 ) );
    $self->{'group'} = new Lire::Group( 'report_spec' => $self->{'spec'} );
    $self->{'group'}->group_fields( [ new Lire::GroupField( 'name' => 'client_host',
                                                            'report_spec' => $self->{'spec'} ),
                                      new Lire::GroupField( 'name' => 'user',
                                                            'report_spec' => $self->{'spec'} ) ] );
    $self->{'group'}->sort_fields( [ 'client_host', 'user' ] );
    $self->{'group'}->limit( '$limit' );

    $self->{'spec'}->calc_spec( $self->{'group'} );

    my $nested = new Lire::Group( 'name' => 'nested',
                                  'report_spec' => $self->{'spec'},
                                  'parent' => $self->{'group'} );
    $self->{'group'}->ops( [ $nested ] );
    $nested->group_fields( [ new Lire::GroupField( 'name' => 'connection_id',
                                                   'report_spec' => $self->{'spec'} ) ] );
    $nested->sort_fields( [ 'connection_id' ] );


    my $nested2 = new Lire::Group( 'name' => 'nested2',
                                  'report_spec' => $self->{'spec'},
                                  'parent' => $nested );
    $nested->ops( [ $nested2 ] );
    $nested2->group_fields( [ new Lire::GroupField( 'name' => 'file',
                                                    'report_spec' => $self->{'spec'} ) ] );
    $nested2->ops( [ tests::MockAggregate->new( 'name' => 'mock',
                                               'report_spec' => $self->{'spec'},
                                               'parent' => $nested ) ] );
    $nested2->sort_fields( [ 'file' ] );
    $nested2->limit( 3 );

    return;
}

sub test_build_dlf_query {
    my $self = $_[0];

    my $test_query = new Lire::DlfQuery( "test" );
    $test_query->add_group_field( 'client_host' );
    $test_query->add_group_field( 'user' );
    $test_query->set_sort_spec( 'client_host user' );
    my $sub = $test_query->create_nested_query();
    $sub->add_group_field( 'connection_id' );
    $sub->set_sort_spec( 'connection_id' );
    my $sub2 = $sub->create_nested_query();
    $sub2->add_aggr_field( '_lr_nrecords', 'count(*)' );
    $sub2->add_aggr_field( 'mock', 'count()' );
    $sub2->add_group_field( 'file' );
    $sub2->set_sort_spec( 'file' );

    my $query = new Lire::DlfQuery( "test" );
    $self->{'group'}->build_query( $query );

    $self->assert_deep_equals( $test_query, $query );
}

sub test__max_entries {
    my $self = $_[0];

    my $group = $self->{'group'};
    my @results = ( [ undef, 0 ],
                    [ '$limit', 4 ],
                    [ 0, 0 ],
                    [ 5, 10 ],
                    [ 10, 15 ],
                    [ 40, 50 ],
                    [ 41, 51 ],
                    [ 50, 55 ],
                    [ 1010, 1060 ] );

    foreach my $r ( @results ) {
        $group->{'limit'} = $r->[0];
        $self->assert_equals( $r->[1], $group->_max_entries() );
    }
}

sub test_create_entry {
    my $self = $_[0];

    my $group_spec = $self->{'group'};
    my $info = new Lire::Report::TableInfo();
    $group_spec->create_categorical_info( $info );
    my $group = new Lire::Report::Group( bless( {}, 'Lire::Report::Entry' ),
                                         $info );


    $self->assert_null( $group_spec->create_entry( $group, { 'client_host' => 'here.com',
                                                             '_lr_nrecords' => 24,
                                                           } ),
                        "create_entry() should return undef when a name is missing" );
    $self->assert_equals( 24, $group->missing_cases() );
    $self->assert_equals( 0, scalar $group->entries() );

    my $entry = $group_spec->create_entry( $group, { 'client_host' => 'localhost',
                                                     'user' => 'flacoste' } );
    $self->assert_not_null( $entry, "create_entry() returned undef" );
    $self->assert_equals( 'localhost', ($entry->data())[0]->{'content'} );
    $self->assert_equals( 'flacoste', ($entry->data())[1]->{'content'} );

    $group->create_entry();
    $group->create_entry();
    $group->create_entry();

    # Test limit
    my $no_entry = $group_spec->create_entry( $group, { 'client_host' => 'localhost',
                                                        'user' => 'flacoste' } );
    $self->assert_null( $no_entry, "create_entry() should return undef when max_entries is reached" );
    $self->assert_equals( 4, scalar $group->entries() );
}

sub test_name {
    my $self = $_[0];

    $self->assert_equals( 'group:client_host.user', $self->{'group'}->name() );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1