#!/usr/local/cpanel/3rdparty/bin/perl

# cpanel - bin/wplogcleaner                        Copyright 2024 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
package bin::wplogcleaner;

use cPstrict;

use Cpanel                  ();
use Cpanel::AccessIds       ();
use Cpanel::Config::Users   ();
use Cpanel::Unix::PID::Tiny ();
use Getopt::Long            ();

use File::pushd;

use constant PID_FILE       => q[/var/cpanel/wplogcleaner.pid];
use constant GLOBAL_TIMEOUT => 12 * 3_600;
use constant DAYS           => 86_400;
use constant LOG_RETENTION  => 10 * DAYS;

our $VERSION = '1.0';

exit( run(@ARGV) // 0 ) unless caller;

sub run (@args) {

    Getopt::Long::GetOptionsFromArray(
        \@args,
        "help|h|?" => \my $print_help,
        "cron|run" => \my $run,
        "user=s"   => \my $only_user,
    );

    return usage() if $print_help;
    if ( !$run ) {
        warn "WRN: Nothing to do, consider using the --run argument.\n";
        return usage(1);
    }

    my @users = Cpanel::Config::Users::getcpusers();

    return 1 unless _acquire_pid();

    foreach my $user ( sort @users ) {

        if ( length $only_user ) {
            next unless $user eq $only_user;
        }

        print "⨀ Deleting old logs for user '$user'\n";

        my $performed = Cpanel::AccessIds::do_as_user(
            $user => \&_user_clean_logs,
        );
    }

    return;
}

sub _acquire_pid {
    my $pidfile    = PID_FILE;
    my $pid_locked = Cpanel::Unix::PID::Tiny::get_run_lock( $pidfile, undef, GLOBAL_TIMEOUT + 1_200 );
    if ( !$pid_locked ) {
        my $running_pid = Cpanel::Unix::PID::Tiny->get_pid_from_pidfile($pidfile) // 0;
        warn("$0 appears to already be running ( process $running_pid holding $pidfile lock )\n");
    }
    return $pid_locked;
}

sub _user_clean_logs {

    Cpanel::initcp();

    my $hd = $Cpanel::homedir or die q[Undefined user homedir];
    die qq[Missing user home directory $hd] unless -d $hd;

    my $logdir = "$hd/.cpanel/logs";
    die qq[Missing user log directory $logdir] unless -d $logdir;

    my $cd = pushd($hd);

    my $now = time;

    {    # purge older logs
        my $purge_ts = $now - LOG_RETENTION;
        opendir( my $logdir_dh, $logdir ) or die("Failed to open directory $logdir: $!");
        while ( my $file = readdir($logdir_dh) ) {
            next unless -f "$logdir/$file";
            next unless ( stat(_) )[9] < $purge_ts;
            unlink "$logdir/$file" or do {
                print("Failed to unlink($logdir/$file): $!");
            };
        }
        closedir($logdir_dh);
    }

    return;
}

sub usage ( $status = 0 ) {

    print <<"EOS";
$0 - Remove old WP2 logs

This script is designed to be run from a crontab to
clean old log files for WordPress Squared instances.

OPTIONS:
    --help | -h     Display this help message
    --cron          Used by the crontab entry to trigger the backups
    --run           Use that argument to run the backup from the command line
    --user=USER     Only run the backups for a single user

Example:
# Run from the crontab
$0 --cron

# or run it manually
$0 --run
$0 --run --user=myuser
EOS

    return $status;
}

1;
