#! /usr/bin/perl

use v5.10;
use strict;
use warnings;
use Pod::Usage;
use File::Basename;
use Time::Local;
use Getopt::Long;
use if $ENV{DEBUG} => "Smart::Comments";
use DNStools::Config qw(get_config);

my %cf;
my $opt_expiry = undef;

MAIN: {
    my %info;    # will hold the information we collected

    GetOptions(
        "e|expiry" => \$opt_expiry,
        "h|help"   => sub { pod2usage(-exit => 0, -verbose => 1) },
        "m|man"    => sub {
            pod2usage(
                -exit      => 0,
                -verbose   => 2,
                -noperldoc => system("perldoc -V &>/dev/null")
            );
        },
    ) or pod2usage;

    %cf = get_config();
    die "$cf{master_dir}: $!\n" if not -d $cf{master_dir};

    foreach my $dir (grep { -d } glob "$cf{master_dir}/*") {

        my $zone = basename($dir);
        $info{$zone} = { status => "OK" };

        if (not -f "$dir/.index.zsk") {
            $info{$zone}{zsk}    = 0;
            $info{$zone}{ksk}    = 0;
            $info{$zone}{kc}     = 0;
            $info{$zone}{end}    = "-";
            $info{$zone}{expiry} = undef;
            next;
        }

        # prueft wie viele zsks genutzt werden
        {
            open(my ($fh), $_ = "<$dir/.index.zsk")
              or die "Can't open $_: $!\n";
            () = <$fh>;
            $info{$zone}{zsk} = $.
        }

        # prueft wie viele ksks genutzt werden
        {
            open(my ($fh), $_ = "<$dir/.index.ksk")
              or die "Can't open $_: $!\n";
            () = <$fh>;
            $info{$zone}{ksk} = $.
        }

        # prueft wie oft die schluessel zum signieren genutzt wurden
        {
            open(my ($fh), $_ = "<$dir/.keycounter")
              or die "Can't open $_: $!\n";
            chomp($info{$zone}{kc} = <$fh>);
        }

        # prueft das ablaufdatum
        if (!-f "$dir/$zone.signed") {
            $info{$zone}{end} = "-";
            next;
        }

        open(my ($fh), $_ = "<$dir/$zone.signed") or die "Can't open $_: $!\n";
        while (<$fh>) {
            next if not /RSIG\s+SOA\s.*\s
				(?<year>\d\d\d\d)
				(?<mon>\d\d)
				(?<day>\d\d)
				(?<hour>\d\d)
				(?<min>\d\d)\d+\s\(/ix;
            $info{$zone}{end} = "$+{day}.$+{mon}.$+{year} $+{hour}:$+{min}";
            $info{$zone}{expiry} =
              timelocal(0, $+{min}, $+{hour}, $+{day}, $+{mon} - 1, $+{year});
        }
    }

    {    # output

        my $sort_by =
          $opt_expiry
          ? sub { ($info{$a}{expiry} // 2**64) <=> ($info{$b}{expiry} // 2**64) }
          : sub { $a cmp $b };

        my $format_h = "%-35s %-8s %1s/%1s %3s %7s\n";
        my $format_l = "%-35s %-8s %1d/%1d %5d %19s\n";

        printf $format_h => qw(Domain Status ZSK KSK Used Sig-end);

        foreach my $zone (sort $sort_by keys %info) {
            printf $format_l => $zone,
              @{ $info{$zone} }{qw(status zsk ksk kc end)};
        }
    }
}

__END__

=head1 NAME

 zone-ls -- lists all zones

=head1 SYNOPSIS

 zone-ls [-e|--expiry]

=head1 DESCRIPTION

This B<zone-ls> lists all zones under control of our dnstools suite. The output is ordered by domain name.

=head1 OPTIONS

=over

=item B<-e>|B<--expiry>

Order the output by expiry date. The sooner the key expires, the more top the
domain is listed.

=back

Additionally the common B<-h>|B<--help>|B<-m>|B<--man> options, which should be
self explanatory.

=head1 AUTHORS

L<andre.suess@pipkin.cc>

=cut

# vim:ts=4 sw=4 ai si aw:
