{{!
    This file is part of Moodle - https://moodle.org/

    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 <http://www.gnu.org/licenses/>.
}}
{{!
    @template file/classes_external

    External function implementation class.

    Context variables required for this template:
    * component
    * component_type
    * component_name
    * copyright
    * self
    * self.classname
    * self.execute_parameters
    * self.execute_phpdoc
    * self.execute_signature
    * self.execute_args
    * self.execute_returns

    Example context (json):
    {
        "component": "local_test",
        "component_type": "local",
        "component_name": "test",
        "copyright": "2021 David Mudrák <david@moodle.com>",
        "self": {
            "classname": "do_something",
            "execute_parameters": "",
            "execute_phpdoc": [],
            "execute_signature": "",
            "execute_args": [],
            "execute_returns": "null"
        }
    }
}}
{{< common/boilerplate_php }}
{{$ description }}External function '{{ component }}_{{ self.classname }}' implementation.{{/ description }}
{{$ package }}{{ component }}{{/ package }}
{{$ extratags }}
 * @category    external
{{/ extratags }}
{{$ copyright }}{{ copyright }}{{/ copyright }}
{{$ namespace }}
namespace {{ component_type }}_{{ component_name }}\external;
{{/ namespace }}
{{$ use }}
use external_api;
use external_description;
use external_function_parameters;
use external_multiple_structure;
use external_single_structure;
use external_value;
{{/ use }}
{{$ requires }}
require_once($CFG->libdir . '/externallib.php');
{{/ requires }}
{{/ common/boilerplate_php }}
class {{ self.classname }} extends external_api {

    /**
     * Describes parameters of the {@see self::execute()} method.
     *
     * @return external_function_parameters
     */
    public static function execute_parameters(): external_function_parameters {

        return new external_function_parameters([{{{ self.execute_parameters }}}]);
    }

    /**
     * TODO describe what the function actually does.
     *
{{# self.execute_phpdoc }}
{{ . }}
{{/ self.execute_phpdoc }}
     * @return mixed TODO document
     */
    public static function execute({{ self.execute_signature }}) {

        // Re-validate parameters in rare case this method was called directly.
        {{# self.has_execute_args }}
        [
        {{# self.execute_args }}
            '{{ . }}' => ${{ . }},
        {{/ self.execute_args }}
        ] = self::validate_parameters(self::execute_parameters(), [
        {{# self.execute_args }}
            '{{ . }}' => ${{ . }},
        {{/ self.execute_args }}
        ]);
        {{/ self.has_execute_args }}

        // Set up and validate appropriate context.
        // TODO Check and eventually replace system context with a different one as needed.
        $context = \context_system::instance();
        self::validate_context($context);

        // Check capabilities.
        require_capability('{{ component_type }}/{{ component_name }}:example', $context);

        // TODO Implement the function and return the expected value.
    }

    /**
     * Describes the return value of the {@see self::execute()} method.
     *
     * @return external_description
     */
    public static function execute_returns(): external_description {

        return {{{ self.execute_returns }}};
    }
}
