#!/usr/bin/perl

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin";

use Data::Dumper;
use Getopt::Long qw(GetOptions);
use Storable qw(dclone);
use Time::HiRes qw(time);
use XymonDNSSEC::Cache;
use XymonDNSSEC::Checks;
use XymonDNSSEC::Config;
use XymonDNSSEC::Guard;
use XymonDNSSEC::Reporter qw(:all);
use XymonDNSSEC::Resolver;

my %DEFAULTS = (
    resolver_timeout      => 5,
    zone_warn_if_no_nsec3 => 1,
    zone_require_permanent_cds_cdnskey 
                          => 1,
    zone_parent_strip_labels 
                          => 1,
    zone_rrsig_delay      => '5d:1d',
    zone_rollover_ds_propagation_delay 
                          => '7d:15d',
    allowed_algorithms    => [ 'RSASHA256', 'RSASHA512', 'ECDSAP256SHA256', 'ECDSAP384SHA384', 'ED25519', 'ED448' ],
    config_file           => '/etc/xymon/xymon-ext-dnssec.yaml',
    test_name             => 'dnssec',
    nameservers           => [],
    hosts_cfg             => '',
    server_options        => {},
    cache_file            => 'xymon-ext-dnssec.cache',
    cache_default_ttl     => 3600,
    permanent_cache_file  => '',        # vide = déduit du cache_file (nouveau)
);

# ========================================================================
# Keep existing functions for backward compatibility
# Import NEW features from XymonDNSSEC::Cache (rollover detection)
# ========================================================================

sub main {
    my @cli_zones;
    my $config_path = $DEFAULTS{config_file};
    my $hosts_cfg_override;
    my $debug = 0;
    my $debug_dns = 0;

    GetOptions(
        'zone=s@'     => \@cli_zones,
        'config=s'    => \$config_path,
        'hosts-cfg=s' => \$hosts_cfg_override,
        'debug!'      => \$debug,
        'debug-dns!'  => \$debug_dns,
    ) or die "Invalid arguments\n";

    push @cli_zones, @ARGV;

    my $cfg = XymonDNSSEC::Config::load_probe_config(\%DEFAULTS, $config_path);
    $$cfg{debug} = $debug;
    $$cfg{debug_dns} = $debug_dns;
    $$cfg{hosts_cfg} = $hosts_cfg_override;
    my $cache = XymonDNSSEC::Cache::load_cache($cfg);

    my $zone_entries = XymonDNSSEC::Config::collect_zone_names($cfg, \@cli_zones);

    if (!@$zone_entries) {
        return 0;
    }

    my $recursive = XymonDNSSEC::Resolver::build_recursive_resolver($cfg);

    for my $entry (@$zone_entries) {
        my %ctx;
        my $bb = new Hobbit({ test => $cfg->{test_name}, hostname => $entry->{zone} });

        $ctx{zone} = $entry->{zone};
        $ctx{bb} = $bb;
        $ctx{trends} = Hobbit::trends($entry->{zone});
        $ctx{recursive} = $recursive;
        $ctx{zone_cache} = {};
        $ctx{zone_status} = {};

        my $guard = XymonDNSSEC::Guard->new(sub { $ctx{trends}->send(); $ctx{bb}->send(); });
        $ctx{cfg} = XymonDNSSEC::Config::merge_zone_options($cfg, $entry->{options});
        $ctx{debug} = $ctx{cfg}{debug};
        $ctx{debug_dns} = $ctx{cfg}{debug_dns};

        if ( exists $cache->{ $entry->{zone} }
          && ref $cache->{ $entry->{zone} } eq 'HASH'
          && exists $cache->{ $entry->{zone} }->{volatile}
          && ref $cache->{ $entry->{zone} }->{volatile} eq 'HASH'
          && ($cache->{ $entry->{zone} }->{volatile}->{expiry} || 0) > time()
        ) {
            $ctx{zone_cache} = dclone( $cache->{ $entry->{zone} }->{volatile} );
        }
        if ( exists $cache->{ $entry->{zone} }
          && ref $cache->{ $entry->{zone} } eq 'HASH'
          && exists $cache->{ $entry->{zone} }->{permanent}
          && ref $cache->{ $entry->{zone} }->{permanent} eq 'HASH'
        ) {
            $ctx{zone_status} = dclone( $cache->{ $entry->{zone} }->{permanent} );
        }        
        my $zone_start_time = time();
        $bb->print("Zone: $ctx{zone}\n");
        {
            my $zone_options = $entry->{options};
            debug(\%ctx, "Zone options: %s", !keys %$zone_options ? 'none' : join(',', map { "$_=$zone_options->{$_}" } sort keys %$zone_options));
        }
        $bb->print("\n");

        XymonDNSSEC::Checks::run_zone_checks(\%ctx);

        # Print elapsed time for this zone
        my $zone_elapsed = time() - $zone_start_time;
        $bb->sprintf("Time: %s\n", human_duration($zone_elapsed, 1));
        # Rebuild in-memory cache entry for this zone according to final color
        $cache->{ $ctx{zone} } = { volatile => {}, permanent => $ctx{zone_status} };
        if ($bb->{color} eq 'green') {
            $cache->{ $ctx{zone} }->{volatile} = $ctx{zone_cache};
        }
    }

    # Conserver uniquement le cache des zones effectivement traitées dans cette exécution.
    my %active_zones = map { $_->{zone} => 1 } @$zone_entries;
    for my $zone (keys %$cache) {
        delete $cache->{$zone} unless $active_zones{$zone};
    }

    # # Save cache once at end of probe execution
    XymonDNSSEC::Cache::save_cache($cfg, $cache);

    return 0;
}

exit main();