use v5.32;

use HTML::TableExtract;
use File::Slurp;
use Data::Dumper;
use List::Util qw(sum);
use Text::SimpleTable::AutoWidth;
use WWW::Mechanize ();

use experimental qw/ signatures /;

unless(caller) {
    my $ts = get_mersenne_results();

    generate_output_table($ts)->draw;
}

sub get_mersenne_results() {

    # log in to Mersenne.org and get results for the last year
    # excluding everything but PHP and DD results

    my $mech = WWW::Mechanize->new;

    my $url =
      'https://www.mersenne.org/results/?extf=1&exp1=1&execm=1&excert=1&exp_lo=2&exp_hi=&limit=10000';

    $mech->get($url);

    $mech->submit_form(
        form_number => 1,
        fields      => {
            user_login    => $ENV{'MERSENNE_USER'},
            user_password => $ENV{'MERSENNE_PASSWORD'},
        } );

    # load the results into a table object
    my $html_string = $mech->content;

    return extract_first_table($html_string);
}

sub extract_first_table($html) {
    $html =~ s/\n//g;

    my $te = HTML::TableExtract->new( depth => 0, count => 2 );

    $te->parse($html);

    return $te->first_table_found;

}

sub generate_output_table ($ts) {

# group GHZ Days results by computer, compute GHZ Days per Day (GHZ Days / Days)
    my $list;

    foreach my $row ( $ts->rows ) {
        foreach my $cell ($row) {
            my $machine  = @$cell[0];
            my $ghz_days = @$cell[6];
            $ghz_days =~ s/\s//g;
            my $days = @$cell[4];
            $days =~ s/\s//g;

            if ( $days > 0 ) {
                my $perf = $ghz_days / $days;
                push $list->{$machine}->@*, $perf;
            }
        }
    }

    # create hash with each comptuer and its average GHz Days per day
    my %ranks;
    foreach my $key ( keys %$list ) {
        my $mean    = sum( @{ $list->{$key} } ) / @{ $list->{$key} };
        my $rounded = int( $mean + 0.5 );
        $ranks{$key} = $rounded;
    }

    # sort hash by the average and print to screen
    my $tbl = Text::SimpleTable::AutoWidth->new(
        captions => [qw/ Computer GHZDaysPerDay /] );

    foreach
      my $key ( reverse sort { $ranks{$a} <=> $ranks{$b} } keys(%ranks) ) {
        $tbl->row( $key, $ranks{$key} );
    }

    return $tbl;
}