<?php
namespace local_treestudyplan;

use \local_treestudyplan\local\gradegenerator;

define('CLI_SCRIPT', true);
require(__DIR__ . '/../../../config.php');
require_once($CFG->libdir . '/clilib.php');
require_once($CFG->dirroot. '/mod/assign/locallib.php');

$usage = "Fill all the gradables in a study plan with random values

Usage:
    # php randomize_grades.php --studyplan=<shortname>  [--file|-f=userfile]
    # php randomize_grades.php --all|-a [--file|-f=userfile]
    # php randomize_grades.php --help|-h

Options:
    -h --help           Print this help.
    -f --file=<value>   Specify file name to store generated user specs in
    -d --dryrun         Do not store grades
";

list($options, $unrecognised) = cli_get_params([
    'help' => false,
    'dryrun' => false,
    'studyplan' => null,
    'all' => false,
    'file' => "/tmp/generategrades.json"
], [
    'h' => 'help',
    's' => 'studyplan',
    'a' => 'all',
    'f' => 'file',
    'd' => 'dryrun'
]);


if ($unrecognised) {
    $unrecognised = implode(PHP_EOL . '  ', $unrecognised);
    cli_error(get_string('cliunknowoption', 'core_admin', $unrecognised));
}

if ($options['help']) {
    cli_writeln($usage);
    exit(2);
}

/////////////////////////////////
$user = get_admin();

if (!$user) {
    cli_error("Unable to find admin user in DB.");
}

$auth = empty($user->auth) ? 'manual' : $user->auth;
if ($auth == 'nologin' or !is_enabled_auth($auth)) {
    cli_error(sprintf("User authentication is either 'nologin' or disabled. Check Moodle authentication method for '%s'",
            $user->username));
}

$authplugin = get_auth_plugin($auth);
$authplugin->sync_roles($user);
login_attempt_valid($user);
complete_user_login($user);


////////////////////////////////


if (empty($options['studyplan']) && empty($options["all"])) {
    cli_error('Missing mandatory argument studyplan.', 2);
}

if(!empty($options["all"])){
    $plans =  studyplan::find_all();
} else {
    $plans = studyplan::find_by_shortname($options["studyplan"]);
}

$generator = new gradegenerator();
$generator->fromFile($options["file"]);


$assignments = [];

cli_writeln(count($plans)." studyplans found:");
foreach($plans as $plan){
    cli_heading($plan->name());
    $users = $plan->find_linked_users();

    foreach($plan->pages() as $page){
        $lines = studyline::find_page_children($page);
        foreach($lines as $line){
            cli_writeln("  ** {$line->name()} **");
            $items = studyitem::find_studyline_children($line);
            foreach($items as $item){
                if($item->type() == studyitem::COURSE) { // only handle courses for now
                    $courseinfo = $item->getcourseinfo();
                    cli_writeln("    # {$courseinfo->shortname()}");

                    if($courseinfo->course()->startdate <= time()){

                        foreach($users as $u){
                            cli_writeln("      -> {$u->firstname} {$u->lastname} <-");
                            $gradables = gradeinfo::list_studyitem_gradables($item);
                            $gen = $generator->generate($u->username,$line->shortname(),$gradables);
                            foreach($gen as $gg){
                                $g = $gg->gi;
                                $gi = $g->getGradeitem();

                                $name = $gi->itemname;
                                $grade = $gg->gradetext;
                                cli_write ("        - {$name} = {$grade}");
                                
                                // Check if the item is alreaady graded for this user
                                $existing = $count = $DB->count_records_select('grade_grades','itemid = :gradeitemid AND finalgrade IS NOT NULL and userid = :userid',
                                    ['gradeitemid' => $gi->id, 'userid' => $u->id]);

                                if(!$existing){
                                    if($gg->grade > 0){
                                        if($gi->itemmodule == "assign"){
                                            // If it is an assignment, submit though that interface 
                                            list($c,$cminfo) = get_course_and_cm_from_instance($gi->iteminstance,$gi->itemmodule);
                                            $cm_ctx = \context_module::instance($cminfo->id);
                                            $a = new \assign($cm_ctx,$cminfo,$c);

                                            $ug = $a->get_user_grade($u->id,true);
                                            $ug->grade = grade_floatval($gg->grade);
                                            $ug->grader = $USER->id;
                                            $ug->feedbacktext = nl2br( htmlspecialchars($gg->fb));
                                            $ug->feedbackformat = FORMAT_HTML;

                                            //print_r($ug);
                                            if(!$options["dryrun"]){
                                                $a->update_grade($ug);
                                                
                                                grade_regrade_final_grades($c->id,$u->id,$gi);
                                                cli_writeln(" ... Stored");
                                            } else {
                                                cli_writeln(" ... (Dry Run)");
                                            }

                                        } else {
                                            // Otherwise, set the grade through the manual grading override
                                            cli_writeln(" ... Cannot store");

                                        }
                                    } else {
                                        cli_writeln(" ... No grade");
                                    }
                                } else {
                                    cli_writeln(" ... Already graded");
                                }
                            }
                        }
                    }
                    else 
                    {
                        cli_writeln("      Skipping since it has not started yet");
                    }
                }
            }
        }
    }
}

$generator->toFile($options["file"]);