#!/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 start() {
    my $serviceManager = new EBox::ServiceManager;
    my @mods = @{$serviceManager->modulesInDependOrder()};
	my @names = map { $_->{'name'} } @mods;
    @names = grep { $_ ne 'apache' } @names;
	push(@names, 'apache');

	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 $status;
  my $msg = "EBox: status module $modname:\t\t\t";
  if ($mod->isEnabled()) {
   print STDOUT $msg . "[ ENABLED ]\n";
   exit 0;
  } 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} . " eBox module: $modname";
  _logActionFunction($msg, $success);
  if ($errorMsg) {
    print STDERR $errorMsg, "\n";
  }
}


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

  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;
