#!/usr/bin/perl

use strict;
use warnings;

# for performance we check first if there are pending operations
unless (grep { -d $_ } </var/lib/zentyal*/conf/userjournal/*>) {
    exit 0;
}

use EBox;
use EBox::Config;
use EBox::Global;
use EBox::Util::Lock;

use Error qw(:try);

use constant LOCK_NAME      => 'zentyal-slave-sync';

my $mode = 'run';
if (($#ARGV == 0) and ($ARGV[0] eq '-l')) {
    $mode = 'list';
}

EBox::init();
my $users = EBox::Global->modInstance('users');
$users->configured() or exit 0;

EBox::Util::Lock::lock(LOCK_NAME);

try {
    @{$users->listSlaves()} or exit 0;
} otherwise {
    exit 0;
};

processDir(EBox::Config::conf() . 'userjournal/');

if (EBox::Global->modExists('usercorner')) {
    eval 'use EBox::UserCorner';
    processDir(EBox::UserCorner::usercornerdir() . 'userjournal/');
}

EBox::Util::Lock::unlock(LOCK_NAME);

exit 0;

sub processSlaveDir
{
    my ($journaldir, $slave) = @_;

    my $host = $slave->{'hostname'};

    if ($mode eq 'list') {
        print "Slave: $host\n";
    }

    my $dir = "$journaldir$host/";

    my $dh;
    opendir($dh, $dir) or
        die "Can't open the journal dir: $dir\n";

    my %files;
    while (defined(my $file = readdir($dh))) {
        (-d "$dir$file" and next);
        $files{$file}=(stat("$dir$file"))[9];
    }
    closedir($dh);

    foreach my $file (sort { $files{$a} cmp $files{$b} } keys %files){
        processFile($slave, "$dir$file");
    }
}

sub processFile
{
    my ($slave, $file) = @_;

    open(FILE, $file);
    my ($method, $param, @params) = <FILE>;
    close(FILE);
    chomp($method);
    chomp($param);
    @params = map { chomp($_); $_ } @params;

    my $client = $users->soapClient($slave);

    if ($mode eq 'run') {
        try {
            $client->$method($param, @params);
            #remove with sudo because it can be a usercorner file
            EBox::Sudo::root("rm -f $file");
        } otherwise {
            EBox::debug("Trying to run method $method with param $param on slave $slave->{'hostname'} failed.");
        };
    } elsif ($mode eq 'list') {
        print " * $method: $param\n";
    }
}

sub processDir
{
    my ($journaldir) = @_;

    my $jdir;
    opendir($jdir, $journaldir) or die "Can't open the journal dir: $journaldir\n";

    while (defined(my $slave = readdir($jdir))) {
        ($slave=~ m/^\./) and next;
        $slave = $users->slaveInfo($slave);
        if ($slave) {
            processSlaveDir($journaldir, $slave);
        }
    }
    closedir($jdir);
}

1;
