<?php
/**
 *
 * @author cfulton
 **/

    if(!isset($CFG)) {
        require('../../../config.php');
    }
    require_once($CFG->libdir.'/datalib.php');
    require_once($CFG->libdir.'/adminlib.php');
    require($CFG->dirroot.'/admin/report/census/lib.php');
    require($CFG->dirroot.'/admin/report/census/version.php');

/// Is Cron running this?
    $cronjob = (isset($cronjob)) ? $cronjob : false;

/// Permissions
    if(!$cronjob) {
        require_login();
        $systemcontext = get_context_instance(CONTEXT_SYSTEM);
        require_capability('moodle/site:doanything', $systemcontext);

    /// Log request
        add_to_log(SITEID, "admin", "report census", "report/census/index.php");

    /// Header
        admin_externalpage_setup('reportcensus');
        admin_externalpage_print_header();
    }
/// Version check
    // Check the version in the database
    // If not present, instantiate the database
    if(!$versioninfo = get_field('census','version','name','census')) {
        $versioninfo = 0;
    }
    
    // Check version
    if($versioninfo != $report->version) {
        require($CFG->dirroot.'/admin/report/census/db/upgrade.php');
        if(!xmldb_newmodule_upgrade($versioninfo)) {
            echo 'ACK!';
            exit;
        } else {
            print_heading(get_string('dbupdated','report_census'));
        }
    }

/// Parse settings
    $allow_remote = get_field('census','allow_remote_reports','name','census');
    $remote_system = get_field('census','remote_server_name','name','census');
    $censusrolesstudents = get_field('census','studentroles','name','census');
    $censusrolesteachers = get_field('census','teacherroles','name','census');
    if(optional_param('submitsettings','',PARAM_TEXT) == 'Save settings') {
        $allow_remote_form = optional_param('phonehome','',PARAM_TEXT);
	$remote_system = optional_param('remoteserver','',PARAM_TEXT);
        $censusrolesstudents = implode(',',optional_param('censusrolesstudents','',PARAM_TEXT));
        $censusrolesteachers = implode(',',optional_param('censusrolesteachers','',PARAM_TEXT));     
	$record = new stdClass();
	$record->id = get_field('census','id','name','census');
	$record->remote_server_name = $remote_system;
        $new_allow_remote = ($allow_remote_form == 'on') ? 1 : 0;	
	if($allow_remote != $new_allow_remote) {
            $record->allow_remote_reports = $new_allow_remote;
            $allow_remote = $new_allow_remote;
        }	
        $record->teacherroles = $censusrolesteachers;
        $record->studentroles = $censusrolesstudents;
        $result = update_record('census', $record);
    }
    $censusrolesstudents = explode(',',$censusrolesstudents);
    $censusrolesteachers = explode(',',$censusrolesteachers);

/// Remote operation check
    // return control if not allowed
    $remote_mode_value = optional_param('remote','',PARAM_TEXT);
    if(!isset($cronjob)) {
        $cronjob = ($remote_mode_value == 'yes') ? true : false;
    }
    if($cronjob && !($allow_remote == 1)) {
        return;
    }
    
/// Hard-coded configuration options (will make moddable later)
    // Sets the time to wait before considering a module active
    // Value is stored in seconds; default is five minutes
    // This is done to ignore the news forum, which is created by default
    $module_creation_time_buffer = 5 * 60;

    // The database prefix for your instance
    // Unless you have multiple instances on the same server, this should be 'mdl'
    $database_prefix = $CFG->prefix;

/// Census method definitions
    $census_method_definitions = array(
        'module' => array('text' => 'Active modules',
                     'db_method' => 'count_records_sql',
                     'db_sql' => "SELECT count($database_prefix"."course_modules.module) 
                                  from $database_prefix"."course_modules inner join $database_prefix"."course on 
                                  $database_prefix"."course_modules.course=$database_prefix"."course.id WHERE 
                                  $database_prefix"."course_modules.added > ($database_prefix"."course.timecreated + $module_creation_time_buffer) 
				  AND $database_prefix"."course.id='{{COURSE_ID}}'"),
        'resource' => array('text' => 'Resources',
                      'db_method' => 'count_records',
                      'db_object' => 'resource',
                      'db_subject' => 'course'),
        'forum_posts' => array('text' => 'Forum posts',
                      'db_method' => 'count_records_sql',
                      'db_sql' => "SELECT count($database_prefix"."forum_posts.id) 
                                  from $database_prefix"."forum_posts,$database_prefix"."forum_discussions 
                                  where $database_prefix"."forum_discussions.id = $database_prefix"."forum_posts.discussion 
                                  and $database_prefix"."forum_discussions.course ='{{COURSE_ID}}'")                    );
    $census_report_definitions = array(
        'teachers' => array(
                       'method' => 'count',
                       'variable' => 'active_teachers',
                       'title' => array('Teachers with active courses')),
        'courses' => array(
                       'method' => 'count',
                       'variable' => 'active_courses',
                       'title' => array('Active courses')),
        'teacher-dist' => array(
                       'method' => 'distribution',
                       'variable' => 'active_teachers',
                       'title' => array('Courses taught','Teachers')),
        'student-dist' => array(
                       'method' => 'distribution',
                       'variable' => 'active_students',
                       'title' => array('Courses taken','Students')),
        'department-dist' => array(
                       'method' => 'simple',
                       'variable' => 'active_department',
                       'title' => array('Department name','Active courses')),
        'class-size' => array(
                       'method' => 'simple',
                       'variable' => 'class_size',
                       'title' => array('Class size','Active courses')),
        'course-format' => array(
                       'method' => 'simple',
                       'variable' => 'course_format',
                       'title' => array('Course format','Active courses')),
    );
                       
/// Census options
    $census_active_options = array('module','resource','forum_posts');    
    $census_collect_options = array_merge($census_active_options, array('template'));
    $census_report_options = array('teachers','courses','teacher-dist','student-dist','department-dist','class-size','course-format');

/// Variable initialization
    // Active course counter
    $stats = array();

/// Get roles from database
    $roles = get_records('role');

/// Settings form
    if(!$cronjob) {
        $checked_text = ($allow_remote == 1) ? 'checked=\"checked\" ' : '';
        print_box_start('generalbox boxwidthwide boxaligncenter centerpara');
        echo '<form method="post" action="." id="settingsform">';
        print_heading(get_string('reportsettings','report_census'));
        echo '<p><input type="checkbox" name="phonehome" id="phonehome" '.$checked_text.'/>'.get_string('form_phonehome','report_census').'</p>';    
        echo '<p><input type="text" name="remoteserver" id="remoteserver" value="'.$remote_system.'" />'.get_string('form_remotesystem','report_census').'</p>';
        print_heading(get_string('form_roleassignment','report_census'));
        echo '<p><table><tr><th>Role</th><th>Teachers</th><th>Students</th></tr>';
        foreach($roles as $role) {
            $teacherchecked = (in_array($role->id,$censusrolesteachers)) ? ' checked="checked"' : '';
            $studentchecked = (in_array($role->id,$censusrolesstudents)) ? ' checked="checked"' : '';
            echo '<tr><td>'.$role->name.'</td>';
            echo '<td><input type="checkbox" name="censusrolesteachers[]" id="censusrolesteachers[]"'.$teacherchecked.' value="'.$role->id.'" /></td>';
            echo '<td><input type="checkbox" name="censusrolesstudents[]" id="censusrolesstudents[]"'.$studentchecked.' value="'.$role->id.'" /></td></tr>';
        }
        echo '</table></p>';
	echo '<p><input type="submit" name="submitsettings" id="submitsettings" value="Save settings" /></p>';
        echo '</form>';
        print_box_end();

    /// Execute census
        print_box_start('generalbox boxwidthwide boxaligncenter centerpara');
        echo '<form method="get" action="." id="runcensusform">';
        print_heading(get_string('runcensus','report_census'));
	echo '<input type="hidden" name="run" id="run" value="yes" />';
        echo '<p><input type="submit" id="submitrun" value="Run census" /></p>';
        echo '</form>';
        print_box_end();
    }

    $run = optional_param('run','no',PARAM_TEXT);
    if($run == 'yes' || $cronjob) {
/// Get all the appropriate data
    // Load roles (cron job for now assumes defaults)
    if(count($censusrolesteachers) < 1 || count($censusrolesstudents) < 1) {
        die(get_string('error_noroles','report_census'));
    } else {
    	$roles = get_records('role');
    	foreach($roles as $role) {
    	    if(in_array($role->id, $censusrolesteachers)) {
    	    	$teacher_roles[] = $role;
    	    }
    	    if(in_array($role->id, $censusrolesstudents)) {
    	        $student_roles[] = $role;
    	    }
    	}
    }
    
    // Get all course ids from given instance
    $courseids = get_fieldset_sql("SELECT DISTINCT id FROM $database_prefix"."course");
    // Go through the course and get all teachers and students
    foreach($courseids as $id) {
        $course_teachers_ids = array();
        $course_students_ids = array();
        $course_census_data = array();

        // Load ids for a given course
        $course_teachers = getCourseMembersByID($id, $teacher_roles);
        $course_students = getCourseMembersByID($id, $student_roles);

        // Merge in id information
        $course_teachers_ids = array_merge(array_keys($course_teachers),$course_teachers_ids);
        $course_students_ids = array_merge(array_keys($course_students),$course_students_ids); 

        // Run census checks
        foreach($census_active_options as $option_id) {
            $option = $census_method_definitions[$option_id];
            $function = $option['db_method'];
            switch($function) {
                case 'count_records':
                  $data = $function($option['db_object'], $option['db_subject'], $id);
                  break;
                case 'count_records_sql':
                  $command = $option['db_sql'];
                  $command = str_replace('{{COURSE_ID}}',$id,$command);
                  $data = $function($command);
		  break;
            }
            $course_census_data[$option_id] = $data;
        }

        // Get course category information
        $cat_id   = get_field( 'course', 'category', 'id', $id);
        $cat_name = get_field( 'course_categories', 'name', 'id', $cat_id);

        // Test whether a course is active
        if(array_sum($course_census_data) > 0) {
            // Add active teachers
            foreach($course_teachers_ids as $item_id) {
                $stats['active_teachers'][$item_id]++;
            }
            
            // Add active students
            foreach($course_students_ids as $item_id) {
                $stats['active_students'][$item_id]++;
            }

            // Increment the course counter
            $stats['active_courses']++;             
            
            // Increment the department/category counter
            $stats['active_department'][$cat_name]++;                   
            
            // Increment class size data
            $class_size_rounded = ceil(count($course_students) / 10);
            $class_size_key = (($class_size_rounded - 1)*10+1) .'-'.($class_size_rounded *10);
            $stats['class_size'][$class_size_key]++;
            
            // Get format information
            $format = get_field('course','format','id',$id);
            $stats['course_format'][$format]++;            
        }	
    }
    // end loop through courses
    
/// Print/Send results
    $stats['census_version'] = $report->version;
    $stats['moodle_version'] = get_field('config','value','name','version');
    foreach($census_report_options as $report) {
        $mode = $census_report_definitions[$report];
        $table->head = $mode['title'];
        $table->data = array();
        switch($mode['method']) {
            case 'count':
                $variable = $mode['variable'];
                $data = (is_array($stats[$variable])) ? count($stats[$variable]) : $stats[$variable];
                $table->data[] = array($data);
                break;
            case 'distribution':
                $variable = $mode['variable'];
                $dist = distribution($stats[$variable]);
                foreach( array_keys($dist) as $seg_idx) {
                    $table->data[] = array($seg_idx, $dist[$seg_idx]);
                }          
                break;
            case 'simple':
                $variable = $mode['variable'];
                foreach( $stats[$variable] as  $key => $item) {
                    $table->data[] = array($key, $item);
                }
                break;
        }
        if(!$cronjob) {
            print_table($table);    
        }
    }
    
    // If remote enabled, send data
    if($cronjob) {
      $hash = get_field('census','remote_hash','name','census');
      if(strlen($hash) != '32') {
          $site = get_field('course','fullname','id',1);
          $hash = md5($site . time());
          $record = new stdClass();
          $record->id = get_field('census','id','name','census');
          $record->remote_hash = $hash;
          $result = update_record('census', $record);
      }
      $stats['id'] = $hash;

      // Setup CURL and transmit
      if(function_exists('curl_init')) {
          $ch = curl_init();
          
          curl_setopt($ch, CURLOPT_URL, $remote_system);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, FALSE);
          curl_setopt($ch, CURLOPT_POST, TRUE);
          curl_setopt($ch, CURLOPT_POSTFIELDS, $stats);
          
          curl_exec($ch);
          curl_close($ch);
          
      } else {
          print_error(get_string('curlerror','report_census'));
      }
    }

    } // end GET test for running census

/// Finish the page
    if(!$cronjob) {
        admin_externalpage_print_footer();
    }
?>
