#!/usr/bin/perl

# cpanel - autofixer/correct_bwdaily              Copyright(c) 2009 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

use strict;
use warnings;

use Getopt::Long;

my $dir = '/var/cpanel/bandwidth';
my $all;
GetOptions(
    'dir=s' => \$dir,
    'all'   => \$all,
) or usage();

die "$dir is not a valid directory.\n" unless -d $dir;

if ($all) {
    opendir my $dh, $dir or die "Unable to read directory $dir\n";
    my @files = grep { !/^\.\.?$/ and !/\.(?:rrd|hour|5min|xml|remainder)$/ and -f "$dir/$_" } readdir $dh;
    closedir $dh;

    my $numbad = 0;
    foreach my $prefix (@files) {
        eval { ++$numbad if update_domain_or_user($prefix); };
        warn $@ if $@;
    }
    print "$numbad files updated.\n";
}
else {
    my $prefix = shift;

    unless ( defined $prefix ) {
        print "Missing required user or domain name.\n";
        usage();
    }
    update_domain_or_user($prefix);
}

sub update_domain_or_user {
    my ($prefix)    = @_;
    my $daily_file  = "$dir/$prefix";
    my $hourly_file = "$dir/$prefix.hour";

    die "No hourly file found for $prefix.\n" unless -f $hourly_file;

    my $daily  = get_daily_data($daily_file);
    my $hdaily = summarize_hourly_data($hourly_file);

    return unless keys %{$hdaily} && keys %{$daily};
    $daily = { %{$daily}, %{$hdaily} };
    open my $fh, '>', $daily_file or die "Unable to re-create $daily: $!\n";
    foreach my $stamp ( sort keys %{$daily} ) {
        print $fh "$stamp=$daily->{$stamp}\n";
    }
    close $fh;
}

sub get_daily_data {
    my ($file) = @_;

    my %h;
    open( my $fh, '<', $file ) or die "Cannot open daily file '$file'\n";
    while (<$fh>) {
        next unless /^(\d+\.\d+\.\d\d\d\d-\w+)=(\d+)/;
        $h{$1} = $2;
    }
    return \%h;
}

sub summarize_hourly_data {
    my ($file) = @_;

    my %h;
    open( my $fh, '<', $file ) or die "Cannot open hourly file '$file'\n";
    while (<$fh>) {
        next unless /^(\d\d\d\d)\.(\d+)\.(\d+)(?:T\d+(?::\d+)?)?-(\w+)=(\d+)/;
        $h{ sprintf '%d.%d.%d-%s', $2 + 0, $3 + 0, $1, $4 } += $5;
    }
    return \%h;
}

sub usage {
    print <<"EOU";
Usage:
    $0 domainname
    $0 username
    $0 --all

Where
    --all     process all domains and users in specified directory
EOU
    exit;
}

