package tests::ReportParserReportBuilderTest;

use strict;

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

use Lire::Report;
use Lire::Report::TableInfo;
use Lire::Report::Subreport;
use Lire::Report::Section;
use Lire::ReportParser::ReportBuilder;
use Lire::Test::Mock;
use Lire::Utils qw/tempfile/;

use Lire::Report::ChartConfig;
use Lire::PluginManager;

use File::Basename qw/dirname/;

sub set_up {
    my $self = $_[0];
    $self->SUPER::set_up();

    $self->{'testdir'} = dirname( __FILE__ );
    $self->{'parser'} = new_proxy Lire::Test::Mock( 'Lire::ReportParser::ReportBuilder' );
    $self->{'parser'}->set_result( 'error' => sub { shift; die @_ } );
    $self->{'parser'}->init_stack( 'lrp_group' );
    $self->{'parser'}->init_stack( 'lrp_group-info' );
    $self->{'parser'}->init_stack( 'lrp_entry' );

    $self->{'table_info'} = new Lire::Report::TableInfo();
    $self->{'table_info'}->create_column_info( 'cell1', 'categorical',
                                               'string' );
    my $group = $self->{'table_info'}->create_group_info( 'group' );
    $group->create_column_info( 'cell2', 'categorical', 'string' );
    $group->create_column_info( 'data1', 'numerical', 'int' );
    $group->create_column_info( 'data2', 'numerical', 'int' );
    $self->{'table_info'}->compute_group_layout();

    $self->{'subreport'} = new Lire::Report::Subreport( 'test', 'test' );
    $self->{'subreport'}->table_info( $self->{'table_info'} );
    $self->{'subreport'}->id( 'test.0' );
    return;
}

sub tear_down {
    my $self = $_[0];
    $self->SUPER::tear_down();

    unlink $self->{'_unlink'} if defined $self->{'_unlink'};

    return;
}

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

    $self->{'parser'}{'curr_subreport'} = $self->{'subreport'};
    $self->{'parser'}->init_stack( 'group' );
    $self->{'parser'}->stack_push( 'group', $self->{'subreport'} );
    $self->{'parser'}->init_stack( 'entry' );
    $self->{'parser'}->stack_push( 'lrp_group', {} );

    $self->{'parser'}->entry_start( 'lire:entry', { 'row-idx' => 0 } );
    $self->assert_equals( 1, $self->{'parser'}->stack_depth( 'entry' ) );
    $self->assert_equals( 0, $self->{'parser'}->stack_peek( 'entry' )->row_idx() );
}

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

    $self->{'parser'}->init_stack( 'group' );
    $self->{'parser'}->stack_push( 'group', $self->{'subreport'} );
    $self->{'parser'}->group_summary_start( 'lire:group-summary',
                                            { 'nrecords' => 24,
                                              'missing-cases' => 1 } );
    $self->assert_equals( 24, $self->{'subreport'}->nrecords() );
    $self->assert_equals( 1, $self->{'subreport'}->missing_cases() );
    $self->assert_null( $self->{'subreport'}->row_idx() );
    $self->{'parser'}->group_summary_start( 'lire:group-summary',
                                            { 'nrecords' => 24,
                                              'missing-cases' => 1,
                                              'row-idx' => 0 } );
    $self->assert_equals( 0, $self->{'subreport'}->row_idx() );
}

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

    $self->{'parser'}{'report'} = new Lire::Report();
    my $now = time;
    $self->{'parser'}->handle_timespan( 'My timespan', $now, $now + 86400,
                                        'daily' );
    $self->assert_num_equals( $now,
                              $self->{'parser'}{'report'}->timespan_start() );
    $self->assert_num_equals( $now + 86400,
                              $self->{'parser'}{'report'}->timespan_end() );
    $self->assert_str_equals( 'daily',
                              $self->{'parser'}{'report'}->timespan_period() );
}

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

    $self->{'parser'}{'report'} = new Lire::Report();
    my $now = time;
    $self->{'parser'}->handle_date( 'My date', $now );
    $self->assert_num_equals( $now, $self->{'parser'}{'report'}->date() );
}

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

    my $subreport = new Lire::Report::Subreport( 'test', 'top-dirs' );
    $subreport->id( 'top-dirs.0' );

    $self->{'parser'}{'report'} = new Lire::Report();
    $self->{'parser'}{'curr_section'} = new Lire::Report::Section();

    $self->{'parser'}->subreport_start( 'lire:subreport',
                                        { 'type' => 'top-dirs',
                                          'superservice' => 'test' } );
    $self->assert_deep_equals( $subreport, $self->{'parser'}{'curr_subreport'} );
    $self->assert_deep_equals( $subreport, $self->{'parser'}{'curr_section'}->subreports() );

    $self->{'parser'}{'curr_section'} = new Lire::Report::Section();
    $self->{'parser'}->subreport_start( 'lire:subreport',
                                        { 'type' => 'top-dirs',
                                          'superservice' => 'test',
                                          'id' => 'my_id' } );
    $subreport->id( 'my_id' );
    $self->assert_deep_equals( $subreport, $self->{'parser'}{'curr_subreport'} );
}

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

    $self->{'parser'}{'curr_subreport'} = $self->{'subreport'};

    $self->{'parser'}->table_start( 'lire:table', { 'show' => 5,
                                                    'charttype' => 'bars' } );

    $self->assert_num_equals( 5, $self->{'subreport'}->show() );
    $self->assert_str_equals( 'bars', $self->{'parser'}{'curr_charttype'} );
}

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

    $self->set_up_chart_types();

    $self->{'parser'}->stack_push( 'lrp_group', {} );
    $self->{'parser'}->stack_push( 'lrp_group-info',
                                   $self->{'subreport'}->table_info() );
    $self->{'parser'}{'curr_subreport'} = $self->{'subreport'};
    $self->{'parser'}->set_result( 'current_table_info' =>
                                   $self->{'subreport'}->table_info() );

    $self->{'parser'}->{'curr_charttype'} = undef;
    $self->{'parser'}->table_info_end();
    $self->assert_num_equals( 0, scalar @{$self->{'subreport'}->chart_configs()} );

    $self->{'parser'}->stack_push( 'lrp_group', {} );
    $self->{'parser'}->stack_push( 'lrp_group-info',
                                   $self->{'subreport'}->table_info() );
    $self->{'parser'}->{'curr_charttype'} = 'pie';
    $self->{'parser'}->table_info_end();
    $self->assert_num_equals( 1, scalar @{$self->{'subreport'}->chart_configs()} );
}

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

    my $info =$self->{'table_info'} = new Lire::Report::TableInfo();
    $info->create_column_info( 'host', 'categorical', 'string', 'Host' );
    my $group = $info->create_group_info( 'file_group' );
    $group->create_column_info( 'file', 'categorical', 'string', 'File' );
    $group->create_column_info( 'downloads', 'numerical', 'int', 'Downloads' );
    $group->create_column_info( 'users', 'numerical', 'int', 'Users' );
    $info->compute_group_layout();

    return;
}

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

    my $sub = new Lire::Report::Subreport( 'test', 'top-files-by-host' );
    $sub->table_info( $self->{'table_info'} );
    $sub->id( 'top-files-by-host.i' );
    $sub->title( 'Top files by host' );
    $sub->schemas( 'test' );
    $sub->description( '<para>File by host report.</para>' );

    $sub->set_summary_value( 'downloads', 'value' => 100 );
    $sub->set_summary_value( 'users', 'value' => 10 );

    my $host = $sub->create_entry();
    $host->add_name( 'Host 1' );

    my $file_group = $host->create_group();
    $file_group->show( 5 );
    $file_group->set_summary_value( 'downloads', 'value' => 64 );
    $file_group->set_summary_value( 'users', 'value' => 8 );

    my $file = $file_group->create_entry();
    $file->add_name( 'File 1' );
    $file->add_value( 'value' => 40 );
    $file->add_value( 'value' => 7 );

    $file = $file_group->create_entry();
    $file->add_name( 'File 2' );
    $file->add_value( 'value' => 24 );
    $file->add_value( 'value' => 1 );

    $host = $sub->create_entry();
    $host->add_name( 'Host 2' );

    $file_group= $host->create_group();
    $file_group->show( 5 );
    $file_group->set_summary_value( 'downloads', 'value' => 36 );
    $file_group->set_summary_value( 'users', 'value' => 2 );

    $file = $file_group->create_entry();
    $file->add_name( 'File 3' );
    $file->add_value( 'value' => 36 );
    $file->add_value( 'value' => 2 );
    $sub->finalize();

    ( $self->{'report'}->sections() )[0]->add_subreport( $sub );
    return;
}

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

    $self->set_up_table_info();

    my $report = $self->{'report'} = new Lire::Report( 'daily', time,
                                                       time + 86400 );
    $report->title( 'My Test Report' );
    $report->description( '<para>Test report</para>' );

    my $section = new Lire::Report::Section( 'First section' );
    $section->description( '<para>A section</para>' );
    $report->add_section( $section );

    $self->set_up_subreport();

    my $cfg = new Lire::Report::ChartConfig();
    $cfg->basename( 'users-downloads-by-file' );
    $cfg->get( 'case_var' )->set( 'file' );
    $cfg->type( Lire::PluginManager->get_plugin( 'chart_type', 'vbars' ) );
    $cfg->type_properties()->get( 'y' )->set( 'downloads' );
    $cfg->type_properties()->get( 'y2' )->set( 'users' );
    $cfg->type_properties()->get( 'numbers' )->set( 1 );
    $self->{'report'}->subreport_by_id( 'top-files-by-host.i' )->add_chart_config( $cfg );

    $cfg = new Lire::Report::ChartConfig();
    $cfg->basename( 'users-downloads-by-host' );
    $cfg->get( 'case_var' )->set( 'host' );
    $cfg->type( Lire::PluginManager->get_plugin( 'chart_type', 'vbars' ) );
    $cfg->type_properties()->get( 'y' )->set( 'downloads' );
    $cfg->type_properties()->get( 'y2' )->set( 'users' );
    $cfg->type_properties()->get( 'numbers' )->set( 1 );
    $self->{'report'}->subreport_by_id( 'top-files-by-host.i' )->add_chart_config( $cfg );

    $section = new Lire::Report::Section( 'Second section' );
    $report->add_section( $section );

    my $sub2 = new_missing Lire::Report::Subreport( 'test', 
                                                    'top-files-by-host',
                                                    'Error' );
    $sub2->id( 'top-files-by-host.ii' );
    $sub2->schemas( 'test' );
    $section->add_subreport( $sub2 );
    return;
}

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

    $self->set_up_chart_types();
    $self->set_up_simple_report();

    my ( $fh, $file ) = tempfile( $self->name() . "_XXXXXX" );
    $self->{'_unlink'} = $file;
    $self->{'report'}->write_report( $fh );
    close $fh;

    system ( "cp $file /tmp/report.xml" );

    my $parser = new Lire::ReportParser::ReportBuilder();
    my $report = $parser->parsefile( $file );
    $report->generator( $self->{'report'}->generator() );
    $self->assert_deep_equals( $self->{'report'}, $report );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1