<?php

namespace local_treestudyplan;
require_once($CFG->libdir.'/externallib.php');

use \grade_item;

// $gi->courseid, 
// $gi->itemmodule, 
// $gi->iteminstance
class gradingscanner 
{
    private static $mod_supported = [];
    private static $course_students = [];
    private $scanner = null;
    private $gi = null;
    private $pending_cache = [];

    public static function supported($mod){
        if(!array_key_exists($mod,self::$mod_supported)){
            self::$mod_supported[$mod] = class_exists("\local_treestudyplan\\local\\ungradedscanners\\{$mod}_scanner");
        }
        return self::$mod_supported[$mod];
    }

    public static function get_course_students($courseid){
        global $CFG;
        if(!array_key_exists($courseid,self::$course_students)){
            $students = [];
            $context = \context_course::instance($courseid);
            foreach (explode(',', $CFG->gradebookroles) as $roleid) {
                $roleid = trim($roleid);
                $students = array_keys(get_role_users($roleid, $context, false, 'u.id', 'u.id ASC'));
            }
            self::$course_students[$courseid] = $students;
        }
        return self::$course_students[$courseid];
    }

    public function __construct(grade_item $gi){
        $this->gi = $gi;
        if(self::supported($gi->itemmodule)) {
            $scannerclass = "\local_treestudyplan\\local\ungradedscanners\\{$gi->itemmodule}_scanner";
            $this->scanner = new $scannerclass($gi);
        }
    }
    
    public function is_available(){
        return $this->scanner !== null;
    }

    public function count_students(){
        return count(self::get_course_students($this->gi->courseid));
    }

    public function count_ungraded(){
        if($this->scanner === null) {
            return -1;
        }
        return $this->scanner->count_ungraded(self::get_course_students($this->gi->courseid));
    }

    public function count_graded(){
        if($this->scanner === null) {
            return -1;
        }
        return $this->scanner->count_graded(self::get_course_students($this->gi->courseid));
    }

    public function pending($userid){
        if(!array_key_exists($userid, $this->pending_cache)){
            if($this->scanner === null) {
                $this->pending_cache[$userid] = false;
            }
            else {
                $this->pending_cache[$userid] = $this->scanner->has_ungraded_submission($userid);;    
            }
        }
        return $this->pending_cache[$userid];
    }    



    public static function structure($value=VALUE_OPTIONAL){
        return new \external_single_structure([
            "ungraded" => new \external_value(PARAM_INT, 'number of ungraded submissions'),
            "graded" => new \external_value(PARAM_INT, 'number of graded students'),
            "students" => new \external_value(PARAM_INT, 'number of students that should submit'),
        ],"details about gradable submissions",$value);
    }

    public function model(){
        return [
            'ungraded' => $this->count_ungraded(),
            'graded' => $this->count_graded(),
            'students' => $this->count_students(),
        ];
    }

}