#!/s/std/bin/perl
#
# gen-ldap-groups-file: extract role information from the database and 
#                       generate group info for import to ldap.
#
# this preliminary version has limited functionality and make 
# certain assumptions
#
# $Id: gen-ldap-group-file.pl,v 1.14 2015/08/06 20:11:37 john Exp $
#

use strict;
use warnings;

use CSL::DBs;
use CSL::Pg;
use DBI; 
use Getopt::Std;
use File::Temp;
use File::Basename;

my $debug = 0;
my $notreal = 0;
my $outfile;
our($opt_d, $opt_n, $opt_o);

sub open_csdb
{
    my $dbh = DBI->connect($CSL::DBs::csdb) 
	|| die "failure to connect to csdb"; 
    $dbh->{RaiseError} = 1;
    $dbh->{PrintError} = 0;
    
    return $dbh;
}


sub do_groups {
    my($dbh, $outfile) = @_;

    my %statusbits = ( 
	'cs_student' => 'cs_student',
	'stat_student' => 'stat_student',
	'csmajor' => 'ugrad',
	'grad' => 'grad',
	'alum' => 'alum',
	'faculty' => 'faculty',
	'vfaculty' => 'vfaculty',
	'lecturer' => 'instructor',
	'staff' => 'staff',
	'labstaff' => 'labstaff',
	'lte' => 'lte',
	'secretary' => 'adminstaff',
	'secondmasters' => 'second_masters',
	'upl' => 'upl',
	'statperson' => 'stat_dept',
	'ta' => 'ta',
	'ra' => 'ra',
	'pa' => 'pa',
	);
    my %flags = (
	'L' => 'CSL_alumni',
	'c' => 'courtesy',
	'o' => 'offsite_collab',
	's' => 'student_staff',
	'J' => 'affiliated_fac',
	'E' => 'emeritus',
	'X' => 'ugrad_cert',
	);
    # group_class_list is used in a "LIKE" query on enrollment
    my %group_class_list = (
	'407001000' => 'iossdk',
	'999029000' => 'iossdk',
	'752%' => 'simicsclasses',
	'757%' => 'simicsclasses',
	'758%' => 'simicsclasses',
	'799%' => 'simicsclasses',
	'899%' => 'simicsclasses',
	'999%' => 'simicsclasses',
	);
    my %groupid = (
	'cs_student' => 800,
	'stat_student' => 801,
	'ugrad' => 802,
	'grad' => 803,
	'alum' => 804,
	'faculty' => 805,
	'vfaculty' => 806,
	'instructor' => 807,
	'staff' => 808,
	'labstaff' => 809,
	'lte' => 810,
	'adminstaff' => 811,
	'second_masters' => 812,
	'upl' => 813,
	'stat_dept' => 814,
	'ta' => 815,
	'ra' => 816,
	'pa' => 817,
	'emeritus' => 818,
	'affiliated_fac' => 819,
	'CSL_alumni' => 820,
	'ugrad_cert' => 821,
	'courtesy' => 822,
	'offsite_collab' => 823,
	'student_staff' => 824,
	'iossdk' => 826,
	'simicsclasses' => 827,
	);

    my $f;
    my $s;
    my $row;
    my $count = 0;
    my($filename, $directories, $suffix) = fileparse($outfile);

    my $fh = File::Temp->new( TEMPLATE => "$filename.XXXXX",
			      DIR => $directories,
			      UNLINK => 0
	);
    my $fname = $fh->filename;
    

    my $query = $dbh->prepare("select * from csdb.people where login is not null");
    $query->execute();
    while ( $row = $query->fetchrow_hashref()) {
	if ( $debug ) {
	    print STDERR $row->{'login'} . " " . $row->{'status'} . "\n";
	}
	$count++;
	foreach $s ( keys %statusbits ) {
	    if ( $row->{$s} == 1 ) {
		print $fh $row->{'login'} . "\t" . $statusbits{$s} . "\t" . $groupid{$statusbits{$s}} . "\tall\n";
	    }
	}
	if ( defined($row->{'status'})) {
	    foreach $f ( keys %flags ) {
		if ( $row->{'status'} =~ /$f/ ) {
		    print $fh $row->{'login'} . "\t" . $flags{$f} . "\t" . $groupid{$flags{$f}} . "\tall\n";
		}
	    }
	}
    }
    #
    # and now.... class-based groups
    #
    my %class_users = ();
    my $orpquery = $dbh->prepare("select p.login from csdb.people p, csorp.enrolled o where o.cid like ? and o.univid = p.univid");
    foreach my $cid ( keys %group_class_list ) {
	my $group = $group_class_list{$cid};
	$orpquery->execute($cid);
	while ( $row = $orpquery->fetchrow_hashref()) {
	    if ( $debug ) {
		print STDERR $row->{'login'} . "\n";
	    }
	    push(@{$class_users{$group}}, $row->{'login'});
	}
    }
    foreach my $group ( keys %class_users ) {
	foreach my $l ( @{$class_users{$group}} ) {
	    print $fh $l . "\t$group\t" . $groupid{$group} . "\tall\n";
	}
    }

    # add labstaff to iossdk group for mac lab testing
    $query = $dbh->prepare("select * from csdb.people where labstaff = 1");
    $query->execute();
    while ( $row = $query->fetchrow_hashref()) {
    	print $fh $row->{'login'} . "\t" . "iossdk" . "\t" . $groupid{'iossdk'} . "\tall\n";
    }
    foreach ('suman', 'mihnea', 'achin' ) {
    	print $fh $_ . "\t" . "iossdk" . "\t" . $groupid{'iossdk'} . "\tall\n";
    }

    close($fh);
    if ( $count > 100 ) {
	# quick sanity check
	rename($outfile, "$outfile.bak");
	rename($fname, $outfile);
    }

}

getopts('dno:');
if ( $opt_d ) {
    $debug++;
}
if ( $opt_n ) {
    $notreal++;
}
if ( $opt_o ) {
    $outfile = $opt_o;
} else {
    die "need -o outfile";
}

# Connect to CSDB
my $csdbh = &open_csdb();

do_groups($csdbh, $outfile);

# Hang up and quit
$csdbh->disconnect;

