<?php
// This file is part of the Studyplan plugin for Moodle
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.

/**
 * Moodle hook functions and some internally used functions
 * @package    local_treestudyplan
 * @copyright  2023 P.M. Kuipers
 * @license    https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/course/modlib.php');

use local_treestudyplan\local\helpers\webservicehelper;
use local_treestudyplan\studyplan;
use core\context;
use core\context\system as context_system;
use core\context\coursecat as context_coursecat;

/**
 * Describe editor options
 * @param context $context Context for options
 * @return array Editor options
 */
function local_treestudyplan_unit_get_editor_options(context $context) {
    global $CFG;
    return ['subdirs' => 1,
            'maxbytes' => $CFG->maxbytes,
            'maxfiles' => -1,
            'changeformat' => 1,
            'context' => $context,
            'noclean' => 1,
            'trusttext' => 0];
}

/**
 * Hook to extend navigation
 * @param global_navigation $navigation Navigation object
 */
function local_treestudyplan_extend_navigation(global_navigation $navigation) {
    global $CFG, $USER;

    if (false && $USER->id > 1) {
        // Don't show if user is not logged in (id == 0) or is guest user (id == 1).
        $userstudyplans = studyplan::find_for_user($USER->id);
        if (!empty($userstudyplans)) {
            // Create invitenode node.
            $invitenode = navigation_node::create(
                get_string("manage_invites", "local_treestudyplan"),
                new moodle_url($CFG->wwwroot . "/local/treestudyplan/invitations.php", []),
                global_navigation::TYPE_CUSTOM,
                null,
                "local_treestudyplan_invitemgmt",
                new pix_icon("invitemgmt", '', 'local_treestudyplan')
            );
            $navigation->add_node($invitenode, 'mycourses');
        }
    }
    // Create invited node.
    $invitenode = navigation_node::create(
        get_string("nav_invited", "local_treestudyplan"),
        new moodle_url($CFG->wwwroot . "/local/treestudyplan/invited.php", []),
        global_navigation::TYPE_USER,
        null,
        "local_treestudyplan_invitemgmt",
        new pix_icon("nav_invited", '', 'local_treestudyplan')
    );
    $navigation->add_node($invitenode, 'mycourses');
}

/**
 * Hook to extend navigation in category view
 * @param mixed $navigation
 * @param context_coursecat $coursecatcontext
 */
function local_treestudyplan_extend_navigation_category_settings($navigation, context_coursecat $coursecatcontext) {
    global $CFG;
    $categoryid = $coursecatcontext->instanceid;

    if (has_capability('local/treestudyplan:editstudyplan', $coursecatcontext)) {
        $navigation->add(
            get_string('treestudyplan:editstudyplan', "local_treestudyplan"),
            new moodle_url($CFG->wwwroot . "/local/treestudyplan/edit-plan.php", ["categoryid" => $categoryid]),
            global_navigation::TYPE_CATEGORY,
            null,
            "local_treestudyplan_editplan",
            new pix_icon("editplans", '', 'local_treestudyplan')
        );
    }

    if (has_capability('local/treestudyplan:viewuserreports', $coursecatcontext)) {
        $navigation->add(
            get_string('link_viewplan', "local_treestudyplan"),
            new moodle_url($CFG->wwwroot . "/local/treestudyplan/view-plan.php", ["categoryid" => $categoryid]),
            global_navigation::TYPE_CATEGORY,
            null,
            "local_treestudyplan_viewplan",
            new pix_icon("viewplans", '', 'local_treestudyplan')
        );
    }
}

/**
 * Map fontawesome icons for use in flat navigation
 * @return array Icon mapping
 *
 */
function local_treestudyplan_get_fontawesome_icon_map() {

    // Create the icon map with the icons which are used in any case.
    $iconmapping = [
            'local_treestudyplan:myreport' => 'fa-vcard',
            'local_treestudyplan:editplans' => 'fa-share-alt',
            'local_treestudyplan:viewplans' => 'fa-share-alt',
    ];
    return $iconmapping;
}

/**
 * Helper function to reset the icon system used as updatecallback function when saving some of the plugin's settings.
 */
function local_treestudyplan_reset_fontawesome_icon_map() {
    // Reset the icon system cache.
    // There is the function \core\output\icon_system::reset_caches() which does seem to be only usable in unit tests.
    // Thus, we clear the icon system cache brutally.
    $cache = \cache::make('core', 'fontawesomeiconmapping');
    $cache->delete('mapping');
    // And rebuild it brutally.
    $instance = \core\output\icon_system::instance(\core\output\icon_system::FONTAWESOME);
    $instance->get_icon_name_map();
}

/**
 * Hook to display fragment of activity/mod settings editor. Used in feature to edit name and description of activity
 * @param mixed $args
 * @return string Rendered form output HTML */
function local_treestudyplan_output_fragment_mod_edit_form($args) {
    global $CFG;
    $args = (object)$args;

    if (empty($args->cmid)) {
        return "RANDOM!";
    }

    // Check the course module exists.
    $cm = \get_coursemodule_from_id('', $args->cmid, 0, false, MUST_EXIST);

    // Check the course exists.
    $course = \get_course($cm->course);

    // Require_login.
    require_login($course, false, $cm); // Needed to setup proper $COURSE.

    [$cm, , $module, $data, $cw] = \get_moduleinfo_data($cm, $course);

    $modmoodleform = "$CFG->dirroot/mod/$module->name/mod_form.php";
    if (file_exists($modmoodleform)) {
        require_once($modmoodleform);
    } else {
        throw new \moodle_exception('noformdesc', 'local_treestudyplan');
    }

    $mformclassname = 'mod_' . $module->name . '_mod_form';
    $mform = new $mformclassname($data, $cw->section, $cm, $course);
    $mform->set_data($data);

    return $mform->render();
}

/**
 * Serve the files from the myplugin file areas.
 *
 * @param stdClass $course the course object
 * @param stdClass $cm the course module object
 * @param stdClass $context the context
 * @param string $filearea the name of the file area
 * @param array $args extra arguments (itemid, path)
 * @param bool $forcedownload whether or not force download
 * @param array $options additional options affecting the file serving
 * @return bool false if the file not found, just send the file otherwise and do not return anything
 */
function local_treestudyplan_pluginfile(
    $course,
    $cm,
    $context,
    string $filearea,
    array $args,
    bool $forcedownload,
    array $options = []
): bool {
    // Check the contextlevel is as expected - the studyplan plugin only uses system context for storing files.
    // This avoids headaches when moving studyplans between contexts, while the security impact is minimal...
    if ($context->contextlevel != CONTEXT_SYSTEM) {
        return false;
    }

    // Make sure the filearea is one of those used by the plugin.
    if (in_array($filearea, ["studyplan", "icon", "studyplanpage"])) {
        // The args is an array containing [itemid, path].
        // Fetch the itemid from the path.
        $itemid = array_shift($args);

        // Studyplan icons and description images are not secret, so don't overdo it on access control...
        if (true) {
            // Extract the filename / filepath from the $args array.
            $filename = array_pop($args); // The last item in the $args array.
            if (empty($args)) {
                // Var $args is empty => the path is '/'.
                $filepath = '/';
            } else {
                // Var $args contains the remaining elements of the filepath.
                $filepath = '/' . implode('/', $args) . '/';
            }

            // Retrieve the file from the Files API.
            $fs = get_file_storage();
            $file = $fs->get_file(context_system::instance()->id, 'local_treestudyplan', $filearea, $itemid, $filepath, $filename);
            if (!$file) {
                // The file does not exist.
                return false;
            }
            // We can now send the file back to the browser - in this case with a cache lifetime of 1 day and no filtering.
            send_stored_file($file, 24 * 60 * 60, 0, $forcedownload, $options);
            return true;
        } else {
            return false;
        }
    } else if (in_array($filearea, ['defaulticon'])) {
        // The args is an array containing [itemid, path].
        // Fetch the itemid from the path.
        $itemid = array_shift($args);

        // Extract the filename / filepath from the $args array.
        $filename = array_pop($args); // The last item in the $args array.
        if (empty($args)) {
            // Var $args is empty => the path is '/'.
            $filepath = '/';
        } else {
            // Var $args contains the remaining elements of the filepath.
            $filepath = '/' . implode('/', $args) . '/';
        }

        // Retrieve the file from the Files API.
        $fs = get_file_storage();
        $file = $fs->get_file(context_system::instance()->id, 'local_treestudyplan', $filearea, $itemid, $filepath, $filename);
        if (!$file) {
            // The file does not exist.
            return false;
        }
        // We can now send the file back to the browser - in this case with a cache lifetime of 1 day and no filtering.
        send_stored_file($file, 24 * 60 * 60, 0, $forcedownload, $options);
        return true;
    } else {
        return false;
    }
}
