#!/usr/bin/perl

use strict;

use EBox;
use EBox::Global;
use EBox::Config;
use EBox::Sudo qw(:all);
use EBox::Exceptions::Internal;


use constant DEFAULTGROUP    => '__USERS__';
use constant DEFAULTGROUPGID => '2000';

my $global = EBox::Global->getInstance(1);
my $users = $global->modInstance('users');

# Initialize the LDAP database
sub init
{
    # Create a new LDAP password for our eBox admin
    my $LDAP_PWD_FILE = EBox::Config::conf() . 'ebox-ldap.passwd';

    my $pass;
    my $newpass = undef;
    if ( -s $LDAP_PWD_FILE ) {
        my $pwdfile;
        my $fd;
        unless (open ($fd, "<$LDAP_PWD_FILE")) {
            throw EBox::Exceptions::External("Can't open $LDAP_PWD_FILE");
        }
        $pass = <$fd>;
        close($fd)
    } else {
        $pass = 'ebox' . rand((2**50));
        $newpass = 1;
    }

    if ($newpass) {
        my $fd;
        unless (open ($fd, ">$LDAP_PWD_FILE")) {
                throw EBox::Exceptions::External("Can't open $LDAP_PWD_FILE");
        }
        print $fd $pass;
        close($fd);
        unless (chmod (0440, $LDAP_PWD_FILE)) {
                throw EBox::Exceptions::External("Can't chmod $LDAP_PWD_FILE");
        }
    }

    # Modify /etc/ldap/slapd.conf
    gen_config();

     # Add dc=ebox and cn=admin,dc=ebox with proper password
    root(EBox::Config::share() . "/ebox-usersandgroups/ebox-ldap-admin");

     # Restart slapd
    root("invoke-rc.d slapd restart");

    # Populate the database
    populate();
}


sub populate
{
	$users->{ldap}->ldapCon;
	my $ldap = $users->{ldap}->{ldap};
	my $dn = $users->usersDn;
	my $result = $ldap->add($dn, attr => [
                                        'ou' => 'Users',
                                        'objectClass' => 'organizationalUnit'
                                             ]);
	($result->is_error) and warn "Cant initialize Users";

	$dn = $users->groupsDn;
	$result = $ldap->add($dn, attr => [
                                        'ou' => 'Groups',
                                        'objectClass' => 'organizationalUnit'
                                          ]);

	($result->is_error) and warn "Cant initialize Groups";

	$users->addGroup(DEFAULTGROUP, 'All users', 1);
}

sub clean 
{
	# clean users
	foreach my $user ($users->users){
		my $username = $user->{'username'};
		$users->delUser($username);		
	}

	# clean groups
	foreach my $group ($users->groups){
		my $groupname = $group->{'account'};
		$users->delGroup($groupname);		
	}
}

sub gen_config
{
	$users->_regenConfig;
}

sub addSysUser
{
	my $user = { 'user' => $_[1], 
		     'fullname' => $_[2],
		     'password' => "{crypt}" . $_[3], 
		     'comment' => $_[4] };

	$users->addUser($user, 1);
}

sub addSysGroup
{

	$users->addGroup($_[1], $_[2]);
}

sub usage
{
	print "Usage: $0 (init | populate | genconfig | addSysUser name fullname pwd commet | addSysGroup name comment)\n";
}

#main 
EBox::init();

if ($#ARGV == -1) {
	usage();
	exit(1);
}

if ($ARGV[0] eq 'populate') {
	populate();
} elsif ($ARGV[0] eq 'genconfig') {
	gen_config();
} elsif ($ARGV[0] eq 'clean') {
	clean();
} elsif ($ARGV[0] eq 'addSysUser') {
	unless ($#ARGV == 4) {
	        usage();
	}
	addSysUser(@ARGV);
} elsif ($ARGV[0] eq 'addSysGroup') {
	unless ($#ARGV == 2) {
	        usage();
	}
	addSysGroup(@ARGV);
} elsif ($ARGV[0] eq 'init') {
    init();
} else {
	usage();
}
