package tests::functional::LireTest;

use strict;

use base qw/ Lire::Test::FunctionalTestCase
             Lire::Test::TestCase
             tests::functional::TestSchemaFixture /;

use POSIX qw/ setlocale LC_MESSAGES /;

use Lire::UI;
use Lire::Test::CursesUIDriver;
use Lire::Config;
use Lire::PluginManager;
use Lire::Config::Parser;

#our @TESTS = qw//;

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

    $self->tests::functional::TestSchemaFixture::init();
    $self->{'driver'} = new Lire::Test::CursesUIDriver();

    return $self;
}

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

    $self->{'_old_lc_messages'} = setlocale( LC_MESSAGES );
    setlocale( LC_MESSAGES, 'C' );

    $self->set_up_test_schemas();
    $self->set_up_test_specs();
    $self->set_up_test_store();
    Lire::Config->init();
    Lire::PluginManager->register_default_plugins();

    $self->set_up_TestDlfConverter();
    $self->set_up_test_analysers();
    $self->set_up_test_another_analyser();

    $self->{'driver'}->setup_curses_ui();

    $self->{'lire_ui'} = new Lire::UI();
    $self->{'driver'}->set_curses_ui( $self->{'lire_ui'}->curses_ui() );

    return;
}

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

    $self->SUPER::tear_down();
    $self->tests::functional::TestSchemaFixture::tear_down();

    $self->{'driver'}->teardown_curses_ui();

    setlocale( LC_MESSAGES, $self->{'_old_lc_messages'} );

    return;
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->select_items( 'section_menu', 'Responder Preferences' );

        $driver->select_items( 'options_list', 'lr_mail_from' );
        $driver->enter_text( 'option_widget',
                             "\ca\ckresponder\@logreport.org" );

        $driver->select_items( 'options_list', 'lr_mail_reply_to' );
        $driver->enter_text( 'option_widget',
                             "\ca\ckresponder\@logreport.org" );

        $driver->select_items( 'options_list', 'lr_archive' );
        $driver->select_items( 'option_widget', 'yes' );

        $driver->select_items( 'section_menu', 'Program Paths' );
        $driver->select_items( 'options_list', 'gzip_path' );
        my $gzip_path = $driver->find_widget( 'option_widget' )->getobj( 'file_field' )->text();
        $self->assert_str_equals( Lire::Config->get( 'gzip_path' ),
                                  $gzip_path );

        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );

    $driver->activate_menu( 'menubar/Lire/Preferences...' );

    my $top_win = $driver->top_window();
    $self->assert_equals( $driver->find_widget( '/quickstart_win' ),
                          $top_win );

    my $prefs_file = $self->homedir() . "/.lire/config.xml";
    $self->assert( -f $prefs_file,
                   "Save didn't write the config file: '$prefs_file'" );

    my $parser =
      new Lire::Config::Parser( 'spec' => Lire::Config->config_spec() );
    my $conf = $parser->load_config_file( $prefs_file );
    $self->assert_str_equals( 'responder@logreport.org',
                              $conf->get( 'lr_mail_from' )->as_value() );
    $self->assert_str_equals( 'responder@logreport.org',
                              $conf->get( 'lr_mail_reply_to' )->as_value() );
    $self->assert_num_equals( 1,
                              $conf->get( 'lr_archive' )->as_value() );

    return;
}

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

    my $driver = $self->{'driver'};

    my $handler = sub {
        $driver->find_widget( 'pathvalue' )->text( $self->homedir() );
        $driver->find_widget( 'filevalue' )->text( 'new_store' );
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );

    $driver->activate_menu( 'menubar/Store/New...' );

    $self->assert( -f $self->homedir() . '/new_store/dlf.db',
                   "new store 'new_store' was not created properly" );
    my $top_win = $driver->top_window();
    $self->assert_str_equals( $driver->find_widget( '/store_win' ),
                              $top_win );

    return;
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->find_widget( 'pathvalue' )->text( $self->{'storedir'} );
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->activate_menu( 'menubar/Store/Open...' );
    $self->assert_str_equals( $driver->find_widget( '/store_win' ),
                              $driver->top_window() );

    $self->assert_dies( qr{no 'New...' submenu in 'menubar/Store' menu},
                        sub {$driver->find_menu_def('menubar/Store/New...')} );
    $self->assert_dies( qr{no 'Open...' submenu in 'menubar/Store' menu},
                        sub {$driver->find_menu_def('menubar/Store/Open...')});

    return;
}

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

    $self->test_open_store();
    my $driver = $self->{'driver'};
    $driver->activate_menu( 'menubar/Store/Close' );
    $self->assert_str_equals( $driver->find_widget( '/quickstart_win' ),
                              $driver->top_window() );

    return;
}

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

    my $driver = $self->{'driver'};
    $self->test_open_store();
    $self->do_add_report_config();
    $self->do_add_import_job();
    $self->do_add_report_jobs();

    $driver->activate_menu( 'menubar/Store/Close' );

    my $parser =
      new Lire::Config::Parser( 'spec' => Lire::Config->config_spec() );

    my $conf = $parser->load_config_file( "$self->{'storedir'}/config.xml" );
    my $e_conf =
      $parser->load_config_file( $self->tests_datadir() . "/jobs-config.xml" );

    $self->assert_deep_equals( $e_conf->get( 'import_jobs' ),
                               $conf->get( 'import_jobs' ) );

    $self->assert_deep_equals( $e_conf->get( 'report_jobs' ),
                               $conf->get( 'report_jobs' ) );
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->enter_text( 'widget/id_widget', 'test.cfg' );
        $self->do_add_section( 'All Files', [],
                               [ [ 'top-files', 'top-files.0',
                                   { 'files_to_show' => 5 } ],
                                 [ 'top-dirs', 'top-dirs.0',
                                   { 'dirs_to_show' => 5 } ],
                                 [ 'downloads-by-period',
                                   'downloads-by-period.0',
                                   { 'period', '15m' },
                                   [ { 'title' => 'Users and Downloads by 15m',
                                       'type' => 'vbars',
                                       'type_props' =>
                                       { 'y' => 'download_count',
                                         'y2' => 'user_count' },
                                       'case_var' => 'timegroup:time_start' } ]
                                 ] ] );
        $self->do_add_section( 'JPEG Files', 
                               [ [ 'select-file', 'select-file.0',
                                   { 'file_match' =>  '.*.jpg$' } ] ],
                               [ [ 'top-files', 'top-files.1',
                                   { 'files_to_show' => 5 } ],
                                 [ 'top-dirs', 'top-dirs.1',
                                   { 'dirs_to_show' => 5 } ],
                                 [ 'downloads-by-period',
                                   'downloads-by-period.1',
                                   { 'period', '15m' } ] ] );

        $self->do_add_section( 'Sessions', [],
                               [ [ 'sessions-by-length',
                                   'sessions-by-length.0' ],
                                 [ 'sessions-by-user_class',
                                   'sessions-by-user_class.0' ] ] );

        $self->do_add_section( 'Download Reports', [],
                               [ [ 'avg-file_size-by-timeslot',
                                   'avg-file_size-by-timeslot.0', ],
                                 [ 'user_downloads-report',
                                   'user_downloads-report', ] ] );

        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->select_items( 'reports/type_widget', 'empty' );
    $driver->click_button( 'reports/buttons', '[Add]' );
    $driver->click_button( 'reports/buttons', '[Ed.]' );
}

sub do_add_section {
    my ( $self, $title, $filters, $specs ) = @_;

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->select_items( 'widget/superservice_widget', 'test' );
        $driver->enter_text( 'widget/title_widget', $title );
        foreach my $f ( @$filters ) {
            $self->do_add_spec( 'filters_widget', $f );
        }
        foreach my $f ( @$specs ) {
            $self->do_add_spec( 'specs_widget', $f );
        }
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'widget/sections_widget/buttons', '[A.]' );
}

sub do_add_chart {
    my ( $self, $chart_cfg ) = @_;

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->enter_text( 'widget/title_widget', $chart_cfg->{'title'} );
        $driver->select_items( 'widget/type_widget/list',
                               $chart_cfg->{'type'} );
        $driver->select_items( 'widget/case_var_widget',
                               $chart_cfg->{'case_var'} );
        my $props_handler = sub {
            $driver->select_items( 'widget/y_widget',
                                   $chart_cfg->{'type_props'}{'y'} );
            $driver->select_items( 'widget/y2_widget',
                                   $chart_cfg->{'type_props'}{'y2'} );
            $driver->click_button( 'buttons', '< OK >' );
        };
        $driver->add_event_loop_handler( $props_handler );
        $driver->click_button( 'widget/type_widget/button', '<...>' );
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'widget/charts_widget/buttons', '[Add]' );
}


sub do_add_spec {
    my ( $self, $widget, $spec ) = @_;

    my ( $type, $id, $params, $charts ) = @$spec;
    $charts ||= [];
    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->enter_text( 'widget/id_widget', $id );
        while ( my ( $name, $value ) = each %$params ) {
            $driver->enter_text( "widget/${name}_widget", $value );
        }
        foreach my $chart ( @$charts ) {
            $self->do_add_chart( $chart );
        }
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->select_items( "widget/$widget/type_widget", $type );
    $driver->click_button( "widget/$widget/buttons", '[A.]' );
    $driver->click_button( "widget/$widget/buttons", '[E.]' );
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->enter_text( 'widget/name_widget', 'Daily Import' );
        $driver->select_items( 'widget/period_widget', 'daily' );
        $driver->select_items( 'widget/service_widget/list', 'test_newapi' );
        $driver->enter_text( 'widget/log_file_widget', 'test.dlf' );

        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'import_jobs/buttons', '[Add]' );
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->enter_text( 'widget/name_widget', 'Test_Report' );
        $self->do_add_daily_schedule();
        $self->do_add_weekly_schedule();
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'report_jobs/buttons', '[Add]' );
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->select_items( 'widget/period_widget', 'daily' );
        $driver->select_items( 'widget/report_config_widget', "test.cfg" );
        $self->do_add_pdf_email_oj();
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'widget/schedules_widget/buttons', '[A.]' );
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->select_items( 'widget/period_widget', 'weekly' );
        $driver->select_items( 'widget/report_config_widget', "test.cfg" );
        $self->do_add_html_file_oj();
        $self->do_add_txt_email_oj();
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'widget/schedules_widget/buttons', '[A.]' );
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->enter_text( 'widget/name_widget', 'PDF' );
        $driver->select_items( 'widget/format_widget/list', 'pdf' );

        $self->set_email_destination( 'PDF Report', 'flacoste@logreport.org' );
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'widget/output_jobs_widget/buttons', '[A]' );
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->enter_text( 'widget/name_widget', 'Text Email' );
        $driver->select_items( 'widget/format_widget/list', 'txt' );
        $self->set_email_destination( 'Text Report', 'wolfgang@logreport.org' );
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'widget/output_jobs_widget/buttons', '[A]' );
}

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

    my $driver = $self->{'driver'};
    my $handler = sub {
        $driver->enter_text( 'widget/name_widget', 'HTML' );
        $driver->select_items( 'widget/format_widget/list', 'html' );
        my $html_properties = sub {
            $driver->select_items( 'widget/xhtml_widget', 'yes' );
            $driver->click_button( 'buttons', '< OK >' );
        };
        $driver->add_event_loop_handler( $html_properties );
        $driver->click_button( 'widget/format_widget/button', '<...>' );

        $self->set_file_destination( "report %Y-W%V" );
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'widget/output_jobs_widget/buttons', '[A]' );
}

sub set_email_destination {
    my ( $self, $subject, @emails ) = @_;
    my $driver = $self->{'driver'};

    $driver->select_items( 'widget/destination_widget/list', 'email' );
    my $handler = sub {
        $driver->enter_text( 'widget/subject_widget', $subject );
        foreach my $email ( @emails ) {
            $driver->enter_text( 'widget/emails_widget/value_widget', $email );
            $driver->click_button( 'widget/emails_widget/buttons', '[Add]' );
        }
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'widget/destination_widget/button', '<...>' );
}

sub set_file_destination {
    my ( $self, $file ) = @_;
    my $driver = $self->{'driver'};

    $driver->select_items( 'widget/destination_widget/list', 'file' );
    my $handler = sub {
        $driver->enter_text( 'widget/file_widget', $file );
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'widget/destination_widget/button', '<...>' );
}

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

    my $driver = $self->{'driver'};
    $self->test_open_store();
    $self->do_add_import_job();
    $self->do_configure_stream( 'test', 'keep_days' => 1,
                                'test-extended' => 'extended',
                                'test-derived' => 'derived'  );
    $self->do_configure_stream( 'test-derived', 'test-extended' => 'none' );
    $driver->activate_menu( 'menubar/Store/Close' );

    my $parser =
      new Lire::Config::Parser( 'spec' => Lire::Config->config_spec() );

    my $conf = $parser->load_config_file( "$self->{'storedir'}/config.xml" );
    my $e_conf =
      $parser->load_config_file( $self->tests_datadir() . "/jobs-config.xml" );

    $self->assert_deep_equals( $e_conf->get( 'streams_config' ),
                               $conf->get( 'streams_config' ) );
}

sub do_configure_stream {
    my ( $self, $stream, %params ) = @_;

    my $driver = $self->{'driver'};
    $driver->select_items( 'streams', $stream );
    my $handler = sub {
        while ( my ( $name, $value ) = each %params ) {
            if ( $name eq 'keep_days' ) {
                $driver->enter_text( 'stream_config/keep_days_widget/text_entry', "\ca\ck1" );
            } else {
                $driver->select_items( "stream_config/${name}_widget/list",
                                       $value );
            }
        }
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'streams_buttons', '[Configure]' );
}

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

    my $driver = $self->{'driver'};
    $self->test_open_store();

    $driver->select_items( 'streams', 'test' );
    my $nrecords = $driver->find_widget( 'nrecords_value' );
    $self->assert_str_equals( 24, $nrecords->text() );

    my $handler = sub {
        $driver->enter_text( 'time_field', '2004-01-01' );
        $driver->click_button( 'buttons', '< OK >' );
    };
    $driver->add_event_loop_handler( $handler );
    $driver->click_button( 'streams_buttons', '[Clean]' );
    $self->assert_str_equals( 0, $nrecords->text() );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1