#!/usr/bin/perl -T

$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';

delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};

use strict;
use warnings;
use Time::Local;

use PVE::Certificate;
use PVE::SafeSyslog;
use PVE::INotify;
use PVE::RESTEnvironment;

use PMG::Utils;
use PMG::Config;
use PMG::ClusterConfig;
use PMG::DBTools;
use PMG::API2::Subscription;
use PMG::API2::APT;
use PMG::API2::Certificates;
use PMG::CertHelpers;
use PMG::NodeConfig;

$SIG{'__WARN__'} = sub {
    my $err = $@;
    my $t = $_[0];
    chomp $t;
    print STDERR "$t\n";
    syslog('warning', "%s", $t);
    $@ = $err;
};

PVE::RESTEnvironment->setup_default_cli_env();

initlog('pmg-daily', 'mail');

my $nodename = PVE::INotify::nodename();

eval { PMG::API2::Subscription->update({ node => $nodename }); };
if (my $err = $@) {
    syslog('err', "update subscription info failed: $err");
}

my $cfg = PMG::Config->new();

if (my $statlifetime = $cfg->get('admin', 'statlifetime')) {
    my $count = 0;
    eval {
        my $dbh = PMG::DBTools::open_ruledb();
        $count = PMG::DBTools::purge_statistic_database($dbh, $statlifetime);
    };
    if (my $err = $@) {
        syslog('err', $err);
    } else {
        syslog('info', "cleanup removed $count entries from statistic database") if $count;
    }
}

# check for available updates
# We assume that users with subscriptions want information
# about new packages.
my $info = eval { PMG::API2::Subscription::read_etc_subscription() };
my $notify = ($info && $info->{status} eq 'active') ? 1 : 0;
eval { PMG::API2::APT->update_database({ node => $nodename, notify => $notify, quiet => 1 }); };
if (my $err = $@) {
    syslog('err', "update apt database failed: $err");
}

# rotate razor log file
rename('/root/.razor/razor-agent.log', '/root/.razor/razor-agent.log.0');

# setup proxy env (assume sa-update use http)
if (my $http_proxy = $cfg->get('admin', 'http_proxy')) {
    $ENV{http_proxy} = $http_proxy;
}

# update spamassassin rules
my $restart_filter = 0;
if (system('sa-update') == 0) {
    # if the exit code is 0, new updates were downloaded
    # then restart the pmg-smtp-filter to load the new rules
    $restart_filter = 1;
}

eval { $restart_filter = 1 if PMG::Utils::update_local_spamassassin_channels(0); };
syslog('err', "$@") if $@;

PMG::Utils::service_cmd('pmg-smtp-filter', 'restart') if $restart_filter;
# run bayes database maintenance
system('sa-learn --force-expire >/dev/null 2>&1');

eval {
    my $node_config = PMG::NodeConfig::load_config();
    my $acme_node_config = PMG::NodeConfig::get_acme_conf($node_config);
    my $acme_domains = $acme_node_config && $acme_node_config->{domains};
    if ($acme_domains) {
        my %typed_domains = map {
            $_ => PMG::NodeConfig::filter_domains_by_type($acme_domains, $_)
        } qw(api smtp);

        foreach my $type (qw(api smtp)) {
            next if !$typed_domains{$type};

            # Guard both certificates separately.
            eval {
                my $cert = PMG::CertHelpers::cert_path($type);
                if (!-e $cert) {
                    syslog(
                        'info',
                        "ACME config found for '$type' certificate, but no custom certificate exists. Skipping ACME renewal until initial certificate has been deployed.",
                    );
                    next;
                }

                if (PVE::Certificate::check_expiry($cert, time() + 30 * 24 * 60 * 60)) {
                    PMG::API2::Certificates->renew_acme_cert({
                        node => $nodename, type => $type });
                } else {
                    syslog(
                        'info',
                        "Custom '$type' certificate does not expire soon, skipping ACME renewal.",
                    );
                }
            };
            syslog('err', "Renewing '$type' ACME certificate failed: $@") if $@;
        }
    }
};
syslog('err', "Renewing ACME certificate failed: $@") if $@;

exit(0);

