#!/usr/bin/perl
### BEGIN INIT INFO
# Provides:          ebox
# Required-Start:    $network
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: eBox platform (network services framework)
### END INIT INFO

use strict;
use warnings;

use EBox::Global;
use EBox;
use EBox::Sudo;
use EBox::ServiceManager;
use File::Slurp;
use Error qw(:try);

EBox::init();
my $global = EBox::Global->getInstance(1);

sub moduleList {
    print "Module list: \n";
    my @mods = @{$global->modInstancesOfType('EBox::Module::Service')};
    my @names = map { $_->{name} } @mods;
    print join(' ', @names);
    print "\n";
}

sub usage {
	print "Usage: $0 start|stop|restart\n";
	print "       $0 <module> start|stop|status|enabled|restart\n";
	exit 1;
}

sub checkModule {
    my ($modname) = @_;
    my $mod = $global->modInstance($modname);
    if (!defined $mod) {
        print STDERR "$modname is not a valid module name\n";
        moduleList();
        exit 2;
    }
    if(!$mod->isa("EBox::Module::Service")) {
        print STDERR "$modname is a not manageable module name\n";
        moduleList();
        exit 2;
    }
    return $mod;
}

sub checkDatabase() {
    unless (-e '/var/lib/ebox/.db-created')  {
        system('sudo /usr/share/ebox/ebox-create-db eboxlogs');
    }
}

sub start() {
    my $serviceManager = new EBox::ServiceManager;
    my @mods = @{$serviceManager->modulesInDependOrder()};
	my @names = map { $_->{'name'} } @mods;
    @names = grep { $_ ne 'apache' } @names;
	push(@names, 'apache');

    checkDatabase();
	foreach my $modname (@names) {
	    moduleAction($modname, 'restartService', 'start');
	}
}

sub stop() {
    my @mods = @{$global->modInstancesOfType('EBox::Module::Service')};
    my @names = map { $_->{'name'} } @mods;
    @names = grep { $_ ne 'apache' } @names;
    push(@names, 'apache');

    foreach my $modname (@names) {
        moduleAction($modname, 'stopService', 'stop');
    }
}


sub moduleAction
{
    my ($modname, $action, $actionName) = @_;
    my $mod = checkModule($modname); #exits if module is not manageable

    # Do not restart apache if we are run under ebox-software
    if ($actionName eq 'restart' and $modname eq 'apache' ) {
        return if (exists $ENV{'EBOX_SOFTWARE'} and
                   $ENV{'EBOX_SOFTWARE'} == 1 );
    }

    my $success;
    my $errorMsg;
    try {
        $mod->$action();
        $success = 0;
    }
    catch EBox::Exceptions::Base with {
        my $ex = shift;
        $success = 1;
        $errorMsg =  $ex->text();
    } otherwise {
        my ($ex) = @_;
        $success = 1;
        $errorMsg = "$ex";
    };

    printModuleMessage($modname, $actionName, $success, $errorMsg);
}

sub status
{
    my ($modname, $action, $actionName) = @_;

    my $mod = checkModule($modname); #exits if module is not manageable

    my $msg = "EBox: status module $modname:\t\t\t";
    my $enabled = $mod->isEnabled();
    my $running = $mod->isRunning();
    if ($enabled and $running) {
        print STDOUT $msg . "[ RUNNING ]\n";
        exit 0;
    } elsif ($enabled and not $running) {
        print STDOUT $msg . "[ STOPPED ]\n";
        exit 0;
    } elsif ((not $enabled) and $running) {
        print STDOUT $msg . "[ RUNNING UNMANAGED ]\n";
        exit 3;
    } else {
        print STDOUT $msg . "[ DISABLED ]\n";
        exit 3;
    }
}

sub _logActionFunction
{
	my ($action, $success) = @_;
	system(". /lib/lsb/init-functions; " .
	       " log_begin_msg \"$action\"; log_end_msg $success");
}

sub printModuleMessage
{
    my ($modname, $action, $success, $errorMsg) = @_;

    my %actions = ( 'start' => 'Starting', 'stop' => 'Stopping',
            'restart' => 'Restarting' );

    my $msg = $actions{$action} . " Zentyal module: $modname";
    _logActionFunction($msg, $success);
    if ($errorMsg) {
        print STDERR $errorMsg, "\n";
    }
}


sub moduleRestart {
    my ($modname) = @_;
    checkDatabase();
    moduleAction($modname, 'restartService', 'restart');
}

sub moduleStop {
    my ($modname) = @_;

    moduleAction($modname, 'stopService', 'stop');
}

sub main
{
    if (@ARGV == 1) {
        if ($ARGV[0] eq 'start') {
            start();
        }
        elsif ($ARGV[0] eq 'restart') {
            stop();
            start();
        }
        elsif ($ARGV[0] eq 'force-reload') {
            stop();
            start();
        }
        elsif ($ARGV[0] eq 'stop') {
            stop();
        } else {
            usage();
        }
    }
    elsif (@ARGV == 2) {
        # action upon one module mode
        my ($modName, $action) = @ARGV;

        if (($action eq 'restart') or ($action eq 'start')) {
            moduleRestart($modName);
        }
        elsif ($action eq 'stop') {
            moduleStop($modName);
        } elsif ($action eq 'status' or $action eq 'enabled') {
            # FIXME: Separate enabled and status actions
            status($modName);
        } else {
            usage();
        }
    } else {
        usage();
    }
}

main();

1;
