#!/usr/bin/env perl

use strict;
use warnings;

use Pod::Usage;
use Getopt::Long;
use File::Basename;

# command line options
my $dirloc = '.'; # directory for searching test cases
my $help;
my $DEBUG = 0;

sub main {
    my $tcCounter = 0;

    GetOptions(
        'help|?'  => \$help,
        'dir|d=s' => \$dirloc,
        'debug'   => \$DEBUG,
    ) or pod2usage(2);

    if ($help) {
        pod2usage(1);
        exit;
    }
    opendir(my $dir, $dirloc) || die "cannot open directory $dirloc";

    my @directories;

    for my $f (readdir $dir) {
        my $d = "$dirloc/$f";

        if (! -d $d) {
            say STDERR qq{Skipping non-directory: $d} if $DEBUG;
            next;
        }

        if ($f =~ /^\./) {
            say STDERR qq{Skipping hidden directory: $d} if $DEBUG;
            next;
        }

        if ($f !~ /-TP$/) {
            say STDERR qq{Skipping directory not ending in "-TP": $d} if $DEBUG;
            next;
        }

        push @directories, $d;
    }

    close $dir;

    @directories = sort { $a cmp $b } @directories;

    foreach my $d (@directories) {
        say STDERR "Processing directory $d" if $DEBUG;
        $tcCounter += tcList($d);
    }

    if ($tcCounter == 0) {
        say STDERR qq{No test cases found};
        say STDERR qq{Use -d to specify directory where all test plans (i.e. directories ending in "-TP") reside};
        exit 1;
    }
}

sub tcList
{
    my $tcDir = shift;

    my $tcCount = 0;
    my $script_name = basename($0);

    my $output = <<"HEADER";
<!-- Content until EOF generated by script $script_name from Zonemaster/Zonemaster utils directory -->

## Test cases list

|Test Case |Test Case Description|
|:---------|:--------------------|
HEADER

    opendir(my $dir, $tcDir);
    my @files = grep { ! /^\./ } readdir $dir;
    close $dir;

    @files = sort {$a cmp $b} @files;

    foreach my $f (@files) {
        next if $f eq "README.md";
        unless ($f =~ /^[a-z]+[0-9]+\.md$/) {
            warn "Skip file with unknown file name pattern: $f\n";
            next;
        }
        $output .= tcName("$tcDir/$f");
        $tcCount++;
    }

    if ( ! grep( /^README\.md$/, @files ) ) {
        warn "No README.md file in folder $tcDir\n";
    }
    else {
        writeReadme( "$tcDir/README.md", $output );
    }

    return $tcCount;
}

sub writeReadme
{
    my ( $tcPath, $tcTable ) = @_;

    # slurp README content until pattern
    my $content = "";
    open( my $in, '<', $tcPath ) or die "Cannot open file $tcPath: $!";
    while( <$in> ) {
        last if /^## Test cases list$/;
        last if /^<!-- Content until EOF generated by script .* -->$/;
        $content .= $_;
    }
    close $in;

    $content .= $tcTable;

    open( my $file, '>', $tcPath ) or die "Cannot open file $tcPath: $!";
    print $file $content;
    close $file;
}

sub tcName
{
    my $tcPath   = shift;
    my $basename = basename($tcPath);
    my $testcase = uc (basename($tcPath, ".md"));

    my $output = "";

    open my $file, $tcPath or die "Cannot open file $tcPath: $!";
    my $header = <$file>;
    if (defined $header) {
        if ($header =~ /^#+ +([A-Z]+[0-9]+): +(.*)/) {

            # For each test case
            $output .= "|[$testcase]($basename)|$2|\n";

            warn "$tcPath: Test case ID does not match on first line\n" unless $1 eq $testcase;
        } else {
            warn "$tcPath: mismatch on first line\n";
        };
    } else {
        warn "$tcPath: empty file or empty first line\n";
    }
    close $file;

    return $output;
}

main();

=head1 NAME

    updateTestPlanReadme

=head1 DESCRIPTION

This tools updates all TestPlans README files with the TestPlan's test cases.

=head1 USAGE

From the root of the project:

    ./utils/updateTestPlanReadme.pl -d docs/public/specifications/tests

Optional arguments:

  --dir      Directory path of the test case directory
  --help     This help text

=cut
