#                                      Copyright 2025 WebPros International, LLC
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited.
#
package Cpanel::UpdateGatherer::modules::EmailStats;

use Cpanel::EximStats::DB::Sqlite ();
use Cpanel::TailWatch::Eximstats  ();
use Cpanel::UpdateGatherer::Std;
use DateTime;

sub compile ( $self, $meta_data ) {
    $meta_data->{email} = _email_stats();
    return 1;
}

sub _email_stats {

    my $email_stats = {
        'total_mail_sent'               => 0,
        'total_mail_received'           => 0,
        'total_mail_processed'          => 0,
        'total_mail_sent_rejected'      => 0,
        'total_mail_received_rejected'  => 0,
        'total_mail_rejected'           => 0,
        'total_mail_sent_delivered'     => 0,
        'total_mail_received_delivered' => 0,
        'total_mail_delivered'          => 0,
        'send_success_rate'             => '0.00%',
        'receive_success_rate'          => '0.00%',
        'send_failure_rate'             => '0.00%',
        'receive_failure_rate'          => '0.00%',
        'total_success_rate'            => '0.00%',
        'total_failure_rate'            => '0.00%',
    };

    return {} if $Cpanel::TailWatch::Eximstats::VERSION < '3.1';

    my $day_ago = _one_day_ago();

    my $dbh = Cpanel::EximStats::DB::Sqlite->dbconnect();

    my @mail_sent = _do_query(
        $dbh,
        "SELECT msgid
        FROM smtp
        WHERE ( transport_method IS 'remote_smtp'
        AND transport_is_remote IS '1' )
        AND sendunixtime > $day_ago"
    );

    my @mail_received = _do_query(
        $dbh,
        "SELECT msgid
        FROM smtp
        WHERE ( transport_method IN ('dovecot_virtual_delivery', 'dovecot_delivery')
        AND transport_is_remote IS '0' )
        AND sendunixtime > $day_ago"
    );

    my @local_send_ids = _do_query(
        $dbh,
        "SELECT msgid
        FROM sends
        WHERE ip IN ('::1', '127.0.0.1', 'localhost')
        AND sendunixtime > $day_ago"
    );

    my @total_mail_received_rejected = _do_query(
        $dbh,
        "SELECT msgid
        FROM failures
        WHERE (router IN ('reject')
        AND ip NOT IN ('::1', '127.0.0.1', 'localhost')
        OR router IN ('virtual_user'))
        AND sendunixtime > $day_ago"
    );

    my @total_mail_sent_rejected = _do_query(
        $dbh,
        "SELECT msgid
        FROM failures
        WHERE (router IN ('reject')
        AND ip IN ('::1', '127.0.0.1', 'localhost')
        OR router IN ('lookuphost'))
        AND sendunixtime > $day_ago"
    );

    $dbh->disconnect();

    my %local_send_ids = map { $_ => 1 } @local_send_ids;
    push @mail_sent, grep { $local_send_ids{$_} } @mail_received;

    $email_stats->{total_mail_sent}      = scalar(@mail_sent) + scalar(@total_mail_sent_rejected);
    $email_stats->{total_mail_received}  = scalar(@mail_received) + scalar(@total_mail_received_rejected);
    $email_stats->{total_mail_processed} = $email_stats->{total_mail_sent} + $email_stats->{total_mail_received};

    $email_stats->{total_mail_sent_rejected}     = scalar(@total_mail_sent_rejected);
    $email_stats->{total_mail_received_rejected} = scalar(@total_mail_received_rejected);
    $email_stats->{total_mail_rejected}          = scalar(@total_mail_received_rejected) + scalar(@total_mail_sent_rejected);

    $email_stats->{total_mail_sent_delivered}     = $email_stats->{total_mail_sent} - scalar(@total_mail_sent_rejected);
    $email_stats->{total_mail_received_delivered} = $email_stats->{total_mail_received} - scalar(@total_mail_received_rejected);
    $email_stats->{total_mail_delivered}          = $email_stats->{total_mail_sent_delivered} + $email_stats->{total_mail_received_delivered};

    $email_stats->{send_success_rate} =
      $email_stats->{total_mail_sent}
      ? sprintf( "%.2f%%", $email_stats->{total_mail_sent_delivered} / $email_stats->{total_mail_sent} * 100 )
      : '0.00%';
    $email_stats->{receive_success_rate} =
      $email_stats->{total_mail_received}
      ? sprintf( "%.2f%%", $email_stats->{total_mail_received_delivered} / $email_stats->{total_mail_received} * 100 )
      : '0.00%';
    $email_stats->{send_failure_rate} =
      $email_stats->{total_mail_sent}
      ? sprintf( "%.2f%%", scalar(@total_mail_sent_rejected) / $email_stats->{total_mail_sent} * 100 )
      : '0.00%';
    $email_stats->{receive_failure_rate} =
      $email_stats->{total_mail_received}
      ? sprintf( "%.2f%%", scalar(@total_mail_received_rejected) / $email_stats->{total_mail_received} * 100 )
      : '0.00%';
    $email_stats->{total_success_rate} =
      $email_stats->{total_mail_processed}
      ? sprintf( "%.2f%%", $email_stats->{total_mail_delivered} / $email_stats->{total_mail_processed} * 100 )
      : '0.00%';
    $email_stats->{total_failure_rate} =
      $email_stats->{total_mail_processed}
      ? sprintf( "%.2f%%", $email_stats->{total_mail_rejected} / $email_stats->{total_mail_processed} * 100 )
      : '0.00%';
    return $email_stats;
}

sub _one_day_ago {
    return DateTime->now( time_zone => "local" )->subtract( hours => 24 )->strftime("%s");
}

sub _do_query ( $dbh, $query ) {
    my @result = ();
    my $sth    = $dbh->prepare($query);
    $sth->execute();
    push @result, $_->[0] foreach @{ $sth->fetchall_arrayref() };
    return @result;
}

1;
