#!/usr/bin/perl

=encoding UTF-8

=head1 DESCRIPTION

Скрипт показывает пейджи с флагми need_update/updating

=head1 PARAMS

 format       - тип вывода [table,jsonl] (table - дефолт). В случае table сначала собираются все даныне, а потом выводятся,
                иначе вывод сразу при получении данных.
 page_id_type - [has,no,any] (any - дефолт). Если any, то покажывает пейджи у которых есть Page ID и пейджи
                у которых Page ID нет. Если has, то показывается только пейджи у которых есть Page ID. Если no,
                то показываются только пейджи без Page ID.
 order        - [update_time] Если не указан, то данные выдаются без сортировки. Имеет смысл только для --format=table
 color        - [auto,on,off] (auto - дефолт). Подсвечивает красным если update_time больше чем на час отличается от текущего
                времени. Если auto, то цвет используется если идет вывод на терминал (а при редиректе цвета не будет). Если on,
                то цвет всегда показывется. Если off, то цвета никогда нет. Имеет смысл только для --format=table

=head1 USAGE

 ./bin/show_bk_sending --page_id_type=has --order=update_time

=cut

use feature 'say';
use Carp;
use Getopt::Long;
use Pod::Usage;
use List::Util qw(max);
use Term::ANSIColor qw(colored);

use lib::abs qw(
  ../lib
  );
use qbit;
use Application;

sub main {

    my $format       = '';
    my $page_id_type = '';
    my $order        = '';
    my $color        = '';

    my $help = 0;
    Getopt::Long::GetOptions(
        'format:s'       => \$format,
        'page_id_type:s' => \$page_id_type,
        'order:s'        => \$order,
        'color:s'        => \$color,
        #---
        'help|?|h' => \$help,
    ) or pod2usage(1);

    pod2usage(-verbose => 2, -noperldoc => 1) if $help;

    $format = 'table' if $format eq '';
    my %known_formats = map {$_ => 1} qw(table jsonl);

    if (!$known_formats{$format}) {
        warn "Unknown format\n";
        pod2usage(-verbose => 2, -noperldoc => 1);
        exit 1;
    }

    $page_id_type = 'any' if $page_id_type eq '';
    my %known_page_id_type = map {$_ => 1} qw(has no any);

    if (!$known_page_id_type{$page_id_type}) {
        warn "Unknown page_id_type\n";
        pod2usage(-verbose => 2, -noperldoc => 1);
        exit 1;
    }

    my %known_order = map {$_ => 1} qw(update_time);

    if ($order && !$known_order{$order}) {
        warn "Unknown order\n";
        pod2usage(-verbose => 2, -noperldoc => 1);
        exit 1;
    }

    if ($format ne 'table' && $order ne '') {
        warn "Option order is not supported in this format\n";
        pod2usage(-verbose => 2, -noperldoc => 1);
        exit 1;
    }

    if ($format ne 'table' && $color ne '') {
        warn "Option color is not supported in this format\n";
        pod2usage(-verbose => 2, -noperldoc => 1);
        exit 1;
    }

    $color = 'auto' if $color eq '';
    my %known_color = map {$_ => 1} qw(auto on off);

    if (!$known_color{$color}) {
        warn "Unknown color\n";
        pod2usage(-verbose => 2, -noperldoc => 1);
        exit 1;
    }

    my $app = Application->new();
    $app->pre_run();

    $app->set_cur_user({id => 0});
    my $tmp_all_rights = $app->add_all_tmp_rights();

    my %heavy_page_ids = map {$_->{page_id} => 1} @{$app->partner_db->heavy_pages->get_all(fields => [qw(page_id)])};

    my $page_with_blocks_accessors = $app->product_manager->get_page_model_accessors();

    my @fields = qw(
      accessor
      id
      page_id
      heavy
      update_time
      multistate
      multistate_name
      );

    my @table;

    if ($format eq 'table') {
        push @table, \@fields;
    }

    foreach my $page_accessor (@$page_with_blocks_accessors) {

        my $data = $app->$page_accessor->get_all(
            fields => [qw(id page_id update_time multistate multistate_name)],
            filter => ['AND' => [{multistate => 'need_update or updating'},]],
        );

        foreach my $el (@{$data}) {

            next if !defined($el->{page_id}) and $page_id_type eq 'has';
            next if defined($el->{page_id})  and $page_id_type eq 'no';

            $el->{multistate_name} =~ s/\n/ /g;

            my $el = {
                accessor        => $page_accessor,
                id              => $el->{id},
                page_id         => $el->{page_id} // 'undef',
                heavy           => ($heavy_page_ids{$el->{page_id} // 'undef'} ? 'H' : '.'),
                update_time     => $el->{update_time},
                multistate      => $el->{multistate},
                multistate_name => $el->{multistate_name},
            };

            if ($format eq 'table') {
                my %h = %$el;
                push @table, [@h{@fields}];
            } elsif ($format eq 'jsonl') {
                say to_json($el);
            } else {
                die "Error in code. This should never happen.";
            }
        }

    }

    if ($format eq 'table') {
        my @width;

        my @sorted_table;

        if ($order eq 'update_time') {
            my $header = shift @table;
            @sorted_table = sort {$a->[4] cmp $b->[4]} @table;
            unshift @sorted_table, $header;
        } else {
            @sorted_table = @table;
        }

        my $i = 0;
        foreach my $row (@sorted_table) {
            if (($color eq 'on') || ($color eq 'auto' && -t STDOUT)) {

                my $now = curdate(oformat => 'sec');
                my $delta = $now - (trdate(db_time => sec => $row->[4]) // 0);

                my $color;
                if ($i == 0) {
                    $color = 'white';
                } elsif ($delta > 3600) {
                    $color = 'red';
                } else {
                    $color = 'white';
                }

                @{$row} = map {colored($_, $color);} @{$row};
            }

            my $j = 0;
            foreach my $el (@{$row}) {
                $width[$j] = max($width[$j] // 0, length($el) + 3);
                $j++;
            }
            $i++;
        }

        my $format = join " ", map {"%-${_}s"} @width;

        foreach my $row (@sorted_table) {
            say sprintf $format, @{$row};
        }

    }

    $app->post_run();
}
main();
