#! /usr/bin/perl

#
# Stuart Raeburn, 08/11/2010
#

use strict;
use lib '/home/httpd/lib/perl/';
use Apache::lonnet;
use Apache::loncommon;
use Apache::lonuserstate;
use Apache::loncoursedata;
use Apache::lonnavmaps;
use LONCAPA qw(:DEFAULT :match);

exit if ($Apache::lonnet::perlvar{'lonRole'} ne 'library');


#  Make sure this process is running from user=www
my $wwwid=getpwnam('www');
if ($wwwid!=$<) {
    my $emailto="$Apache::lonnet::perlvar{'lonAdmEMail'},$Apache::lonnet::perlvar{'lonSysEMail'}";
    my $subj="LON: $Apache::lonnet::perlvar{'lonHostID'} User ID mismatch";
    system("echo 'User ID mismatch. refresh_courseids_db.pl must be run as user www.' |\
 mail -s '$subj' $emailto > /dev/null");
    exit 1;
}
#
# Let people know we are running
open(my $fh,'>>'.$Apache::lonnet::perlvar{'lonDaemons'}.'/logs/buildlastlogin.log');
print $fh "==== buildlastlogindb.pl Run ".localtime()."====\n";

my @domains = sort(&Apache::lonnet::current_machine_domains());

my (%users,%gotdbs);
$env{'allowed.bre'} = 'F';

foreach my $dom (@domains) {
    next unless ($dom eq 'gcitest');
    my %courseshash;
    my @ids=&Apache::lonnet::current_machine_ids();
    my %currhash = &Apache::lonnet::courseiddump($dom,'.',1,'.','.','.',1,\@ids,'.');
    foreach my $cid (sort(keys(%currhash))) {
        my ($cdom,$cnum) = split(/_/,$cid); 
        my $path =&propath($cdom,$cnum);
        my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,
                              ['previous','active','future']);
        $env{'request.course.id'} = $cid;
        $env{'request.role'} = 'cc./'.$cdom.'/'.$cnum;
        my ($furl,$ferr)=
            &Apache::lonuserstate::readmap($cdom.'/'.$cnum);
        my $navmap = Apache::lonnavmaps::navmap->new();
        my (%symbs,%surveys,%stusubmissions);
        if (defined($navmap)) {
            foreach my $res ($navmap->retrieveResources('/uploaded/'.$cdom.'/'.$cnum.'/default_1261144274.sequence',sub { $_[0]->is_problem() },1,0)) {
                my $symb = $res->symb();
                $symbs{$symb} = $res->parts();
                if ($res->is_survey()) {
                    $surveys{$symb} = 1;
                }
            }
        }
        foreach my $user (keys(%advrolehash)) {
            my ($uname,$udom,$rest) = split(/:/,$user,3);
            if (&check_for_gci_dc($uname,$udom)) {
                next;
            }
            $users{$uname.':'.$udom} = 1;
        }
        my $classlist=&Apache::loncoursedata::get_classlist($cdom,$cnum);
        if (ref($classlist) eq 'HASH') {
            foreach my $student (keys(%{$classlist})) {
                if ($student =~/^($LONCAPA::match_username)\:($LONCAPA::match_domain)$/) {
                    my ($tuname,$tudom)=($1,$2);
                    if (&check_for_gci_dc($tuname,$tudom)) {
                        next;
                    }
                    $users{$student} = 1;
                    my %StudentsData;
                    my @tmp = &Apache::loncoursedata::get_current_state($tuname,$tudom,undef,$cid);
                    if ((scalar @tmp > 0) && ($tmp[0] !~ /^error:/)) {
                        %StudentsData = @tmp;
                    }
                    foreach my $symb (keys(%symbs)) {
                        my $resource_data = $StudentsData{$symb};
                        if (ref($symbs{$symb}) eq 'ARRAY') {
                            foreach my $partnum (@{$symbs{$symb}}) {
                                if (exists($resource_data->{'resource.'.$partnum.'.solved'})) {
                                    if ($resource_data->{'resource.'.$partnum.'.solved'} =~ /^correct_/) {
                                        $stusubmissions{$student."\0correct"} ++;
                                    }
                                }
                                if (exists($resource_data->{'resource.'.$partnum.'.tries'})) {
                                    if ($surveys{$symb}) {
                                        $stusubmissions{$student."\0surveysubs"} += $resource_data->{'resource.'.$partnum.'.tries'};
                                    } else {
                                        $stusubmissions{$student."\0attempts"} += $resource_data->{'resource.'.$partnum.'.tries'};
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        undef($navmap);
        if (keys(%stusubmissions) > 0) {
            my $putresult = &Apache::lonnet::put('nohist_submissiontracker',\%stusubmissions,
                                                 $cdom,$cnum);
            if ($putresult eq 'ok') {
                print $fh "stored stusubmission data for $cdom".'_'."$cnum\n";
            }
        }
    }
}

delete($env{'allowed.bre'});
delete($env{'request.course.id'});
delete($env{'request.role'});

my %lastlogin;
foreach my $user (sort(keys(%users))) {
    my ($uname,$udom) = split(/:/,$user);
    &readactivitylog($uname,$udom,\%lastlogin,\%gotdbs);
}

foreach my $key (sort(keys(%lastlogin))) {
    if (ref($lastlogin{$key}) eq 'HASH') {
        if ($key =~ /^($match_domain)_($match_courseid)$/) {
            my $cdom = $1;
            my $cnum = $2;
            my $putresult = &Apache::lonnet::put('nohist_crslastlogin',$lastlogin{$key},
                                                 $cdom,$cnum);
            if ($putresult eq 'ok') {
                print $fh "stored lastalogin data for $key\n";
            }
        }
    }
}

## Finished!
print $fh "==== buildlastlogindb.pl completed ".localtime()." ====\n";
close($fh);
exit;

sub readactivitylog {
    my($uname,$udom,$lastlogin,$gotdbs) = @_;
    my $path = &propath($udom,$uname);
    if (-e "$path/activity.log") {
        if (open(my $fh,"<$path/activity.log")) {
            while (<$fh>) {
                chomp();  
                if (m{^(\d+):\w+:Role\s+(cc|in|ta|ep|st|ad)\./(gcitest)/($match_courseid)/?([^/]*)}) {
                    next if ($gotdbs->{$3.'_'.$4});
                    $lastlogin->{$3.'_'.$4}{$uname.':'.$udom.':'.$5.':'.$2} = $1;
                }
            }
            close($fh);
        }
    }
}

sub check_for_gci_dc {
    my ($uname,$udom) = @_;
    my $now=time;
    my $numdc = 0;
    my %roles = &Apache::lonnet::get_my_roles($uname,$udom,'userroles',undef,['dc']);
    foreach my $dom ('gci','gcitest') {
        if ($roles{':'.$dom.':dc'}) {
            $numdc++;
        }
    }
    return $numdc;
}

