#!/usr/bin/perl

# cpanel - packages-enXim                         Copyright(c) 2012 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cpanel license. Unauthorized copying is prohibited
# $Desc$

use strict;
use warnings;

use File::Path ();

my %PACKAGE_DEFAULTS = (
    'ip'          => 'n',
    'cgi'         => 'y',
    'hasshell'    => 'n',
    'maxftp'      => 'unlimited',
    'maxsql'      => 'unlimited',
    'maxpop'      => 'unlimited',
    'maxlst'      => 'unlimited',
    'maxsub'      => 'unlimited',
    'maxpark'     => 0,
    'maxaddon'    => 0,
    'bwlimit'     => 0,
    'quota'       => 0,
    'cpmod'       => 'x3',
    'lang'        => 'en',
    'featurelist' => 'default',
);

my $virtualhosting_plan_dir = '/etc/virtualhosting/plans';

my $plan_names = get_plan_names();

#
# In the rare or impossible event that no plan names are found, write a small
# placeholder to satisfy WHM.
#
unless ( @{$plan_names} ) {
    my $dir  = '/var/cpanel/packages';
    my $file = "$dir/unsupported";

    File::Path::mkpath($dir) or die("File::Path::mkpath(): Unable to create directory $dir: $!");

    open( my $fh, '>', $file ) or die("Unable to open $file for writing: $!");
    print {$fh} "FEATURELIST=unsupported\n";
    close $fh;

    exit 0;
}

foreach my $plan_name ( @{ get_plan_names() } ) {
    my $package = {%PACKAGE_DEFAULTS};
    my $updater = update_package($plan_name);

    $updater->(
        'bandwidth',
        sub {
            if ( is_enabled( 'bandwidth', $_ ) ) {
                $package->{'bwlimit'} = $_->{'bandwidth'}{'default'}{'threshold'} / 1024 / 1024;
            }
        }
    );

    $updater->(
        'subdomain',
        sub {
            if ( is_enabled( 'subdomain', $_ ) ) {
                $package->{'maxsub'} = $_->{'subdomain'}{'default'}{'max'};
            }
        }
    );

    $updater->(
        'mysql',
        sub {
            if ( is_enabled( 'mysql', $_ ) ) {
                $package->{'maxsql'} = $_->{'mysql'}{'default'}{'dbasenum'};
            }
            else {
                $package->{'maxsql'} = 0;
            }
        }
    );

    $updater->(
        'proftpd',
        'users',
        sub {
            if ( is_enabled( 'proftpd', $_ ) ) {
                $package->{'maxftp'} = $_->{'users'}->{'default'}->{'maxusers'};
            }
        }
    );

    $updater->(
        'cgi',
        sub {
            if ( !is_enabled( 'cgi', $_ ) ) {
                $package->{'cgi'} = 'n';
            }
        }
    );

    $updater->(
        'diskquota',
        sub {
            if ( is_enabled( 'diskquota', $_ ) ) {
                $package->{'quota'} = int $_->{'diskquota'}->{'default'}->{'quota'};
            }
        }
    );

    $updater->(
        'aliases',
        sub {
            $package->{'maxpark'} = is_enabled( 'aliases', $_ ) ? 'unlimited' : 0;
        }
    );

    $updater->(
        'ssh',
        sub {
            if ( is_enabled( 'ssh', $_ ) ) {
                $package->{'hasshell'} = 'y';
            }
        }
    );

    $updater->(
        'users',
        sub {
            $package->{'maxpop'} = $_->{'users'}->{'default'}->{'maxusers'};
        }
    );

    $updater->(
        'ipinfo',
        sub {
            if ( is_enabled( 'ipinfo', $_ ) && $_->{'ipinfo'}->{'default'}->{'namebased'} eq '0' ) {
                $package->{'ip'} = 'y';
            }
        }
    );

    write_package( $plan_name, $package );
}

sub write_package {
    my ( $plan_name, $package ) = @_;

    my $path = '/var/cpanel/packages';
    if ( !-e $path ) {
        system( 'mkdir', '-p', $path );
    }

    if ( open( my $fh, '>', "$path/$plan_name" ) ) {
        while ( my ( $key, $value ) = each %$package ) {
            printf {$fh} "%s=%s\n", uc $key, $value;
        }
        close($fh);
    }
}

sub is_enabled {
    my ( $file_name, $data ) = @_;
    if ( exists $data->{$file_name}->{'default'}->{'enabled'} && $data->{$file_name}->{'default'}->{'enabled'} ) {
        return 1;
    }
    else {
        return;
    }
}

sub update_package {
    my ($plan_name) = @_;

    return sub {
        my $code      = pop @_;
        my @file_name = @_;

        my $data = {};
        foreach my $file_name (@file_name) {
            my $full_path = $virtualhosting_plan_dir . '/' . $plan_name;
            $data->{$file_name} = data_file( $file_name, $full_path );
        }

        local $_ = $data;
        $code->($data);
    };

}

sub data_file {
    my ( $plan_file, $path ) = @_;

    my $full_path = $path . '/' . $plan_file;

    my $stash = {};
    if ( open( my $fh, '<', $full_path ) ) {
        my $section = 'default';
        while ( my $line = <$fh> ) {
            chomp($line);
            if ( $line =~ /^\[(.*)\]/ ) {
                $section = lc $1;
                next;
            }

            if ( $line =~ /\=/ ) {
                my ( $key, $value ) = split /\s*\=\s*/, $line;
                $stash->{$section}{$key} = $value;
            }
        }
    }

    return $stash;
}

sub get_plan_names {
    opendir( my $dir_h, $virtualhosting_plan_dir ) || do {
        print "Unable to open $virtualhosting_plan_dir\n";
        exit 1;
    };

    return [ grep { !/^\.\.?$/ } readdir $dir_h ];
}

