#!/usr/bin/perl -w
# $Id$
# This script (sophomorix-groupdel) is maintained by Rüdiger Beck
# It is Free Software (License GPLv3)
# If you find errors, contact the author
# jeffbeck@web.de  or  jeffbeck@gmx.de


# Bibliotheken
use strict;
use Getopt::Long;
Getopt::Long::Configure ("bundling");
use Sophomorix::SophomorixConfig;
use Sophomorix::SophomorixBase;
use Sophomorix::SophomorixAPI;
use DBI;
use Net::LDAP;

use Sophomorix::SophomorixPgLdap qw(show_modulename
                                    check_connections
                                    remove_class_db_entry
                                    pg_get_group_type
                                    fetchadmins_from_adminclass
                                    fetchworkstations_from_room
                                    fetchstudents_from_adminclass
                                    fetchrooms_from_school
                                    fetchadminclasses_from_school
                                   );


my @arguments = @ARGV;


# ===========================================================================
# Variablen
# ==========================================================================

my $help=0;
my $info=0;

# ===========================================================================
# Optionen verarbeiten
# ==========================================================================
$Conf::log_level=1;
my $room="";
my $class="";
my $delete_all_empty_classes=0;

my $backup=1;
my $remove_teachers=0;

my $explanation="";
my $skiplock=0;

my $type=-1; # 3: domain group

# Parsen der Optionen
my $testopt=GetOptions(
           "verbose|v+" => \$Conf::log_level,
           "help|h" => \$help,
           "info|i" => \$info,
           "room=s" => \$room,
           "c|class=s" => \$class,
           "skiplock" => \$skiplock,
           "delete-all-empty-classes" => \$delete_all_empty_classes,
           "remove-teachers" => \$remove_teachers,
           "backup!" => \$backup,
          );

# Prüfen, ob Optionen erkannt wurden, sonst Abbruch
&check_options($testopt);

# --info
if ($info==1){
    my $count=0;
    print "Looking for classes without users:\n";
    my @classes = &fetchadminclasses_from_school("showhidden");
    foreach my $class (@classes){
        my @users = &fetchstudents_from_adminclass($class);
        my $members=$#users+1;

        my @teachers=&fetchadmins_from_adminclass($class);
        my $teacher=$#teachers+1;

        if ($members==0){
	    $count++;
            print "  * $class has $members members ($teacher teachers)\n";
       }
    }
    print "$count classes are without users.\n";
    exit;
}

if ($room eq ""
    and $class eq ""
    and $delete_all_empty_classes==0){
    $help=1;
}

# --help
if ($help==1) {
   # Scriptname ermitteln
   my @list = split(/\//,$0);
   my $scriptname = pop @list;
   # Befehlsbeschreibung
   print('
sophomorix-groupdel deletes groups without users from the sophomorix database (and ldap)

Options
  -h  / --help
  -v  / --verbose
  -vv / --verbose --verbose
  --skiplock

  --room name  (a group for workstations)
  --class name (a group for students)
  --delete-all-empty-classes
  
  --backup   (default)
  --nobackup
  

Please see the sophomorix-groupdel(8) man pages for full documentation
');
   print "\n";
   exit;
}




&check_connections();
&log_script_start(@arguments);




# --room name
if ($room ne ""){
    # 1) check if $room is really a room
    print "Checking if room $room is a room: ";
    my $seen=0;
    my @rooms = &fetchrooms_from_school();
    foreach my $existing_room (@rooms){
        if ($room eq $existing_room){
	    $seen=1;
            print "Yes\n";
            last;
        }
    }
    if ($seen==0){
        my ($type)=&pg_get_group_type($room);
        print "No ($type)\n";
        &log_script_exit("WARNING: Not removing room $room",1,1,0,@arguments);
    }

    # 2) check if there are no users in this room
    print "Checking if room $room can be removed\n";
    my @users = &fetchworkstations_from_room($room);
    my $members=$#users+1;
    print "   $room has $members workstations\n";
    if ($members==0){
	print "   Removing room $room from pg\n";
    } else {
        print "   Group $room is not empty\n";
        &log_script_exit("WARNING: Not removing room $room",1,1,0,@arguments);
    } 

    # Remove files/dirs

    # Do it
    &remove_class_db_entry($room);
}


# --class name
if ($class ne ""){
    &remove_class($class,$backup);
}


# --delete-all-empty-classes
if ($delete_all_empty_classes==1){
    my @classes = &fetchadminclasses_from_school("showhidden");
    foreach my $class (@classes){
        print "Checking if $class can be deleted\n";
        my @users = &fetchstudents_from_adminclass($class);
        my $members=$#users+1;
        if ($members==0){
	    &remove_class($class,$backup);
       }
    }
    &log_script_exit("All empty classes deleted",1,1,0,@arguments);
    exit;
}



&log_script_end(@arguments);





######################################################################
# subs
######################################################################

sub remove_class {
    my ($class,$backup) = @_;
    # 1) check if $class is really a adminclass/hiddenclass
    print "Checking if class $class is a adminclass/hiddenclass: ";
    my $seen=0;
    my @classes = &fetchadminclasses_from_school("showhidden");
    foreach my $existing_class (@classes){
        if ($class eq $existing_class){
            my ($type)=&pg_get_group_type($class);
	    $seen=1;
            print "Yes ($type)\n";
            last;
        }
    }
    if ($seen==0){
        my ($type)=&pg_get_group_type($class);
        print "No ($type)\n";
        print "   WARNING: Not removing class $class\n";
        exit;
    }

    # 2) check if there are no users in this class
    print "Checking if class $class can be removed\n";
    my @users = &fetchstudents_from_adminclass($class);
    my $members=$#users+1;
    print "   $class has $members students\n";
    if ($members==0){
	#print "   Removing class $class\n";
    } else {
        print "   Group $class is not empty\n";
        print "   WARNING: Not removing class $class\n";
        exit;
    } 

    # 3) check if teachers are in this class (as admins)
    my @teachers=&fetchadmins_from_adminclass($class);
    my $teacher=$#teachers+1;
    print "   $class has $teacher teachers\n";
    if ($teacher==0){
	#print "   Removing class $class\n";
    } else {
        print "   Group $class is not empty\n";
        print "   WARNING: Not removing class $class\n";
        if ($remove_teachers==1){
            print "   I am removing the teachers as you wish!\n";
            foreach my $teach (@teachers){
                print "Removing $teach from $class\n";
                my $command="sophomorix-teacher --remove $class --teacher $teach";
                print "   $command\n";
                system("$command");
            }
        } else {
            print "   Use --remove-teachers if you want to go on!\n";
            return;
        }
    } 


    # Do it!
    print "   Removing class $class\n";
    my $timestamp=&zeit_stempel();
    # Remove files/dirs
    &backup_dir_to_attic("${DevelConf::homedir_pupil}/$class",
                         "groupdel",
                         "${timestamp}_groupdel_${class}",
                         "homedir_${class}",
                         "",
                         "$backup");
    &backup_dir_to_attic("${DevelConf::share_classes}/$class",
                         "groupdel",
                         "${timestamp}_groupdel_${class}",
                         "share_${class}",
                         "",
                         "$backup");
    &backup_dir_to_attic("${DevelConf::tasks_classes}/$class",
                         "groupdel",
                         "${timestamp}_groupdel_${class}",
                         "tasks_${class}",
                         "",
                         "$backup");
    &backup_dir_to_attic("${DevelConf::www_classes}/$class",
                         "groupdel",
                         "${timestamp}_groupdel_${class}",
                         "www_${class}",
                         "bzip2",
                         "$backup");
    &remove_class_db_entry($class);
}
