#! /usr/bin/perl

# COPYRIGHT
#   Copyright (C) 2008 gNewSense Community <http://www.gnewsense.org>
#   Parts of this code come from PFV_info
# copyrighted (C) by 2007 Markus Laire <malaire@gmail.com>
# under the Perl license
#
#
# LICENSE
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
# USAGE (command-line)
# $ perl PathToKFV_SummaryTable.pl/KFV_SummaryTable.pl > MyOutputFile
#
# You can then copy and paste from the MyOutputFile file to the wiki page. Don't forget to
# delete it after use !

use strict;
use warnings FATAL => 'all';
use LWP::Simple qw(get);
use Time::Local qw(timegm);

##### error-function #####

sub error($) {
    print "ERROR: @_\n";
    exit;
}

my @MONTHS = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my %MONTHS = map { $MONTHS[$_] => $_ } 0..$#MONTHS;


##### save table in a matrix ######

my $SummaryTable_url = "http://wiki.gnewsense.org/Kernel/Image?action=source";

my $SummaryTable_heading = "Driver sections in KERNEL";

my $SummaryInput = get($SummaryTable_url);
error "Failed to retrieve $SummaryTable_url" unless defined $SummaryInput;

my @SummaryTable;

# Find a table following heading $SummaryTable_heading
$SummaryInput =~ m#!!$SummaryTable_heading\s*((?:\n\|\|.+)+)#i
    or error "Can't find the table. Format seems to have changed";
my $SummaryTable = $1;
# Remove initial newline
$SummaryTable =~ s#\n##;

# Process lines
for (split /\n/, $SummaryTable) {
    # Skip table-attribute-lines
    next unless m#\|\|$#;
    # Skip table-header-line
    next if m#^\|\|!#;

    # Get columns
    s#^\|\|##;
    s#\|\|$##;
    push @SummaryTable, [ split m#\s*\|\|\s*# ];
}

# ========== Check table data ==========

for my $n (0..$#SummaryTable) {
    my @row = @{$SummaryTable[$n]};
    # Information for error-messages
    my $err = "at row " . ($n+1) . ":\n" . join("\n", @row);

    if (@row != 8) {
        error "Wrong number of columns $err";
    }

    # Column 0: Section                     - Not checked
    # Column 1: Owner                       - Not checked
    # Column 2: Date adopted                - Not checked
    # Column 3: Package number              - Not checked
    # Column 4: % completed                 - '?' or '\d\d?%'
    # Column 5: % certified free            - '?' or '\d\d?%'
    # Column 6: suspected non-free reported - Not checked
    # Column 7: Date of summary (DD MMM YY) - '?' or 'DD MMM YY'
    if ($row[4] !~ m#^(\?|\d+%)$#) {
        error "Invalid value for '% completed' column $err";
    }
    if ($row[5] !~ m#^(\?|\d+%)$#) {
        error "Invalid value for '% certified free' column $err";
    }
    if ($row[7] =~ m#^\?$#){
        next;
    } elsif ($row[7] !~ m#^(\d\d) (\w\w\w) (\d\d)$#) {
        error "Invalid value for 'Date of summary' column $err";
    } elsif (not exists $MONTHS{$2}) {
        error "Invalid month for 'Date of summary' column $err";
    }
}

##### Parse the table #####

print "|| border=1\n";
print "||!Section||!Owner||!Date adopted (DD MMM YY)||!Total number of files in section (including README's etc.)||!Percentage of section completed||!Percentage of section certified free||!All suspected non-free software reported (Yes/ No or N/A if none to report)||!Date of summary (DD MMM YY)||\n";

for my $row (@SummaryTable) {
    if($$row[1] !~ /NEEDS\s*ADOPTING/ && $$row[1] !~ /PRIORITY\s*ADOPTION/ ) {
        if($$row[3] !~ /\?/){
            my $SubTable_url = $$row[0];
            $SubTable_url =~ s/\[*(.*)\|.*\]+.+\]+.*/$1\?action=source/;
            if ($SubTable_url =~ /wiki:/) {
                $SubTable_url =~ s/wiki:/http:\/\/wiki\.gnewsense\.org\//;
            }
            my $SubTableInput = get($SubTable_url);
            error "Failed to retrieve $SubTable_url" unless defined $SubTableInput;

            my @SubTable;

            # Find a table following || border=1
#            print $SubTableInput;
            $SubTableInput =~ m#\|\|\s*border=1\s*((?:\n\|\|.+)+)#i
            or error "Can't find the table. Format seems to have changed";
            my $SubTable = $1;
            # Remove initial newline
            $SubTable =~ s#\n##;

            # Process lines
            for (split /\n/, $SubTable) {
            # Skip table-attribute-lines
            next unless m#\|\|$#;
            # Skip table-header-line
            next if m#^\|\|!#;

            # Get columns
            s#^\|\|##;
            s#\|\|$##;
            push @SubTable, [ split m#\s*\|\|\s*# ];
            }

            # ========== Check table data ==========

            for my $n (0..$#SubTable) {
                my @row = @{$SubTable[$n]};
                # Information for error-messages
                my $err = "at row " . ($n+1) . ":\n" . join("\n", @row);

                if (@row != 8) {
                    error "Wrong number of columns $err";
                }

                # Column 0: Section                     - Not checked
                # Column 1: Owner                       - Not checked
                # Column 2: Date adopted                - Not checked
                # Column 3: Package number              - Not checked
                # Column 4: % completed                 - '?' or '\d\d?%'
                # Column 5: % certified free            - '?' or '\d\d?%'
                # Column 6: suspected non-free reported - Not checked
                # Column 7: Date of summary (DD MMM YY) - '?' or 'DD MMM YY'
                if ($row[4] !~ m#^(\?|\d+%)$#) {
                    error "Invalid value for '% completed' column $err";
                }
                if ($row[5] !~ m#^(\?|\d+%)$#) {
                    error "Invalid value for '% certified free' column $err";
                }
                if ($row[7] =~ m#^\?$#){
                    next;
                } elsif ($row[7] !~ m#^(\d\d) (\w\w\w) (\d\d)$#) {
                    error "Invalid value for 'Date of summary' column $err";
                } elsif (not exists $MONTHS{$2}) {
                    error "Invalid month for 'Date of summary' column $err";
                }
            }

            my $Sum_Percent_Section_Checked = 0;
            my $Sum_Percent_Section_Free = 0;
            my $suspected_nonfree_reported = 0;
            my $suspected_nonfree_nonreported = 0;
            my $suspected_nonfree_unknown = 0;

            for my $row_subtable (@SubTable) {
                if($$row_subtable[1] !~ /NEEDS\s*ADOPTING/ && $$row_subtable[1] !~ /PRIORITY\s*ADOPTION/ ) {
                    if($$row_subtable[3] !~ /\?/) {

                        my $nb_packages_line = $$row_subtable[3];
                        my $percent_packages_checked = $$row_subtable[4];
                        $percent_packages_checked =~ s/\%//;
                        my $percent_packages_free = $$row_subtable[5];
                        $percent_packages_free =~ s/\%//;

                        if ($percent_packages_checked !~ /\?/) {
                            $Sum_Percent_Section_Checked += $nb_packages_line * $percent_packages_checked;
                        } else {
                            next;
                        }

                        if ($percent_packages_free !~ /\?/) {
                            $Sum_Percent_Section_Free += $nb_packages_line * $percent_packages_free;
                        } else {
                            next;
                        }

                        if ($$row_subtable[4] ne $$row_subtable[5] && $$row_subtable[6] =~ /Yes/i) {
                            $suspected_nonfree_reported += 1;
                        } elsif ($$row_subtable[4] ne $$row_subtable[5] && $$row_subtable[6] =~ /No/i) {
                            $suspected_nonfree_nonreported += 1;
                        } elsif ($$row_subtable[4] ne $$row_subtable[5] && $$row_subtable[6] =~ /N\/A/i) {
                            $suspected_nonfree_unknown += 1;
                        } elsif ($$row_subtable[4] ne $$row_subtable[5]) {
                            error "Formatting of the column _suspected non-free reported_ uncorrect";
                        } else {
                            next;
                        }
                    } else {
                        next;
                    }
                } elsif($$row_subtable[1] =~ /NEEDS\s*ADOPTING/ || $$row_subtable[1] =~ /PRIORITY\s*ADOPTION/ ) {
                    next;
                }
            }

            print "||" . $$row[0] . "||" . $$row[1] . "||" . $$row[2] . "||";

            my $Percent_section_checked = $Sum_Percent_Section_Checked / $$row[3];
            my $Percent_section_free = $Sum_Percent_Section_Free / $$row[3];
            print $$row[3] . "||";

            $$row[4] = $Percent_section_checked;
            $$row[4] =~ s/(\.\d\d)\d*/$1%/;
            print $$row[4] . "||";

            $$row[5] = $Percent_section_free;
            $$row[5] =~ s/(\.\d\d)\d*/$1%/;
            print $$row[5] . "||";

            if ($suspected_nonfree_reported == 0 && $suspected_nonfree_unknown == 0) {
                $$row[6] = "No";
            } elsif ($suspected_nonfree_nonreported == 0 && $suspected_nonfree_unknown == 0) {
                $$row[6] = "Yes";
            } else {
                $$row[6] = "N/A";
            }
            print $$row[6] . "||";

            (my $sec,my $min,my $hour,my $mday,my $month,my $year,my $sday,my $aday,my $isdst) = gmtime(time);
            $year += 1900;
            $year =~ s/\d\d(\d\d)/$1/;
            $$row[7] = $mday . " " . $MONTHS[$month] . " " . $year;
            print $$row[7];
            print "||\n";

        } else {
            next;
        }
    } elsif($$row[1] =~ /NEEDS\s*ADOPTING/ || $$row[1] =~ /PRIORITY\s*ADOPTION/ ) {
        print "||" . $$row[0] . "||" . $$row[1] . "||" . $$row[2] . "||" . $$row[3] . "||0%||0%||" . $$row[6] . "||";

        (my $sec,my $min,my $hour,my $mday,my $month,my $year,my $sday,my $aday,my $isdst) = gmtime(time);
        $year += 1900;
        $year =~ s/\d\d(\d\d)/$1/;
        $$row[7] = $mday . " " . $MONTHS[$month] . " " . $year;
        print $$row[7] . "||\n";
        next;
    }
}
