<?xml version="1.0" encoding="UTF-8"?>
<ajxp_plugin id="action.scheduler" enabled="false" label="CONF_MESSAGE[Tasks Scheduler]" description="CONF_MESSAGE[Register tasks to be run on a regular basis instead of writing them one by one in cron tab.]"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:../core.ajaxplorer/ajxp_registry.xsd">
    <client_settings>
        <resources>
            <i18n namespace="action.scheduler" path="plugins/action.scheduler/i18n"/>
            <img_library alias="scheduler" path="plugins/action.scheduler/icons"/>
            <js className="Scheduler" file="plugins/action.scheduler/build/Scheduler.js" depends="React"/>
        </resources>
    </client_settings>
    <registry_contributions>
        <client_configs>
            <template element="ajxp_desktop" name="scheduler_style" position="after"><![CDATA[
            <style>
                .scheduler-list .mui-toolbar-group.mui-left {
                    width: 88% !important;
                }
            </style>
            ]]></template>
        </client_configs>
        <actions>
            <action name="scheduler_menu">
                <gui text="action.scheduler.18" iconClass="icon-time" title="action.scheduler.18d" src="scheduler/ICON_SIZE/player_time.png" hasAccessKey="false">
                    <context selection="false" dir="" recycle="hidden" allowedMimes="scheduler_zone"
                             actionBar="true" contextMenu="false" infoPanel="false" actionBarGroup="put"/>
                </gui>
                <subMenu>
                    <dynamicItems>
                        <item actionId="scheduler_addTask"></item>
                        <item actionId="scheduler_runAll"></item>
                        <item actionId="scheduler_generateCronExpression"></item>
                    </dynamicItems>
                </subMenu>
            </action>
            <action name="scheduler_generateCronExpression">
                <gui text="action.scheduler.20" title="action.scheduler.20d" iconClass="icon-paste" src="scheduler/22/shellscript.png" hasAccessKey="false">
                    <context selection="false" dir="" recycle="hidden" allowedMimes="scheduler_zone"
                             actionBar="false" contextMenu="true" infoPanel="true"
                             actionBarGroup="user"/>
                </gui>
                <processing>
                    <clientCallback prepareModal="true" dialogOpenForm="scheduler_cronExpression" dialogOkButtonOnly="true" dialogSkipButtons="false">
                        <dialogOnOpen><![CDATA[
                            var connexion = new Connexion();
                            connexion.setParameters(new Hash({get_action:'scheduler_generateCronExpression'}));
                            connexion.onComplete = function(transport){
                                $("cron_expression").setValue(transport.responseText);
                                $("cron_expression").select();
                            };
                            connexion.sendAsync();
                        ]]></dialogOnOpen>
                        <dialogOnComplete><![CDATA[
                                hideLightBox();
                                ]]></dialogOnComplete>
                    </clientCallback>
                    <clientForm id="scheduler_cronExpression"><![CDATA[
                         <div id="scheduler_cronExpression" box_width="420">
                             <div class="dialogLegend" ajxp_message_id="action.scheduler.21">AJXP_MESSAGE[action.scheduler.21]</div>
                             <textarea class="dialogFocus" style="width:400px;height:80px; margin-top: 5px;" id="cron_expression"></textarea>
                         </div>
                    ]]></clientForm>
                    <serverCallback methodName="switchAction" developerComment="Generate a correct expression to be inserted in Crontab, in order to trigger the {runAll} action on a regular basis."/>
                </processing>
            </action>
            <action name="scheduler_runAll">
                <gui text="action.scheduler.15" title="action.scheduler.16d" iconClass="icon-play-circle" src="scheduler/22/media_playback_start.png" hasAccessKey="false">
                    <context selection="false" dir="" recycle="hidden" allowedMimes="scheduler_zone"
                             actionBar="false" contextMenu="true" infoPanel="true"
                             actionBarGroup="user"/>
                </gui>
                <processing>
                    <clientCallback><![CDATA[
                        var connexion = new Connexion();
                        connexion.setParameters(new Hash({get_action:'scheduler_runAll'}));
                        connexion.onComplete = function(transport){
                            PydioApi.getClient().parseXmlMessage(transport.responseXML);
                        };
                        connexion.sendAsync();
                    ]]></clientCallback>
                    <serverCallback methodName="switchAction" developerComment="Run the scheduler: check if some tasks must be run now, and launch them. Generally launched from command line."/>
                </processing>
            </action>
            <action name="scheduler_loadTask">
                <processing>
                    <serverCallback methodName="handleTasks" developerComment="Returns a JSON representation of the task parameters">
                        <input_param description="The id of the task to run" name="task_id" type="string" mandatory="true"/>
                    </serverCallback>
                </processing>
            </action>
            <action name="scheduler_addTask">
                <gui text="action.scheduler.8" title="action.scheduler.9" iconClass="icon-plus" src="scheduler/22/task_add.png" hasAccessKey="false">
                    <context selection="false" dir="" recycle="hidden" allowedMimes="scheduler_zone"
                             actionBar="false" contextMenu="true" infoPanel="true"
                             actionBarGroup="put">
                    </context>
                </gui>
                <processing>
                    <clientCallback prepareModal="true" dialogOpenForm="scheduler-task-form" dialogOkButtonOnly="false" dialogSkipButtons="false">
                       <dialogOnOpen><![CDATA[
                           this.currentFormManager = new FormManager();
                           var xmlDefinition = ajaxplorer.getXmlRegistry();
                           var node = XPathSelectSingleNode(xmlDefinition, 'actions/action[@name="scheduler_addTask"]/processing/standardFormDefinition');

                           this.currentFormManager.params = this.currentFormManager.parseParameters(node, "param");

                           if(window.actionArguments && window.actionArguments[0]){
                               var tId = window.actionArguments[0].getPath();
                               tId = getBaseName(tId);
                               this.currentFormManager.task_id = tId;
                               var conn = new Connexion();
                               conn.setParameters(new Hash({get_action:'scheduler_loadTask',task_id:tId}));
                               var values;
                               conn.onComplete = function(transport){
                                    values = $H(transport.responseJSON);
                                   this.currentFormManager.createParametersInputs(
                                        $('scheduler-task-form'),
                                        this.currentFormManager.params,
                                        true,
                                        values
                                   );
                               }.bind(this);
                               conn.sendAsync();
                           }else{
                               this.currentFormManager.createParametersInputs(
                                    $('scheduler-task-form'),
                                    this.currentFormManager.params,
                                    true
                               );
                           }
                       ]]></dialogOnOpen>
                        <dialogOnComplete><![CDATA[

                            /**
                             * @author Jordi Salvat i Alabart - with thanks to <a href="www.salir.com">Salir.com</a>.
                             */
                            var regStr = "^\\s*((\\*(\/\\d+)?|([0-5]?\\d)(-([0-5]?\\d)(\/\\d+)?)?(,([0-5]?\\d)(-([0-5]?\\d)(\/\\d+)?)?)*)\\s+(\\*(\/\\d+)?|([01]?\\d|2[0-3])(-([01]?\\d|2[0-3])(\/\\d+)?)?(,([01]?\\d|2[0-3])(-([01]?\\d|2[0-3])(\/\\d+)?)?)*)\\s+(\\*(\/\\d+)?|(0?[1-9]|[12]\\d|3[01])(-(0?[1-9]|[12]\\d|3[01])(\/\\d+)?)?(,(0?[1-9]|[12]\\d|3[01])(-(0?[1-9]|[12]\\d|3[01])(\/\\d+)?)?)*)\\s+(\\*(\/\\d+)?|([1-9]|1[012])(-([1-9]|1[012])(\/\\d+)?)?(,([1-9]|1[012])(-([1-9]|1[012])(\/\\d+)?)?)*|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\\s+(\\*(\/\\d+)?|([0-7])(-([0-7])(\/\\d+)?)?(,([0-7])(-([0-7])(\/\\d+)?)?)*|mon|tue|wed|thu|fri|sat|sun)\\s*$|(@yearly|@annually|@monthly|@weekly|@daily|@midnight|@hourly)\\s*$)";

                            /*
                               form validation
                            */
                            var schLabel = $('scheduler-task-form').select('[name=label]')[0];
                            // $('scheduler-task-form').select('[name=schedule]')[0].removeClassName('SF_failed')
                            var schSch = $('scheduler-task-form').select('[name=schedule]')[0];
                            var schUser = $('scheduler-task-form').select('[name=user_id]')[0];
                            var schRepoId = $('scheduler-task-form').select('[name=repository_id]')[0];
                            var schActionName = $('scheduler-task-form').select('[name=action_name]')[0];

                            schSch.value = schSch.value.trim();
                            /* check null value */

                            var errorMsg = "";

                            if( schLabel.value === "" ||
                                schSch.value === "" ||
                                schUser.value === "" ||
                                schRepoId.value === "" ||
                                schActionName.value === "loading"){
                                    (schLabel.value === "" )?schLabel.addClassName("SF_failed"):schLabel.removeClassName("SF_failed");
                                    (schSch.value === "")?schSch.addClassName("SF_failed"):schSch.removeClassName("SF_failed");
                                    (schUser.value === "")?schUser.addClassName("SF_failed"):schUser.removeClassName("SF_failed");
                                    (schRepoId.value === "")?schRepoId.addClassName("SF_failed"):schRepoId.removeClassName("SF_failed");
                                    (schActionName.value === "")?schActionName.addClassName("SF_failed"):schActionName.removeClassName("SF_failed");
                                    alert("Some fields should not be empty");
                                    return 0;
                                }
                            /* check schedule format */
                            if(schSch.value.match(regStr) != null){
                                schSch.removeClassName("SF_failed");
                            }else{
                                schSch.addClassName("SF_failed");
                                alert("Check format of Schedule");
                                return 0;
                            }

                            var values = new Hash({});
                            this.currentFormManager.serializeParametersInputs(
                                $('scheduler-task-form'),
                                values,
                                '');

                            var conn = new Connexion();
                            values.set('get_action', 'scheduler_addTask');
                            if(this.currentFormManager.task_id){
                                values.set('task_id',this.currentFormManager.task_id);
                            }
                            conn.setParameters(values);
                            conn.sendAsync();
                            conn.onComplete = function(transport){
                                var res = PydioApi.getClient().parseXmlMessage(transport.responseXML);
                                if(res) hideLightBox();
                            };
                       ]]></dialogOnComplete>
                    </clientCallback>
                    <clientForm id="scheduler-task-form"><![CDATA[
                        <div id="scheduler-task-form" box_width="300"></div>
                    ]]></clientForm>
                    <standardFormDefinition>
                        <param name="label" group="action.scheduler.23" label="action.scheduler.12" description="action.scheduler.12d" type="string" mandatory="true"/>
                        <param name="schedule" group="action.scheduler.23" label="action.scheduler.2" description="action.scheduler.2d" type="string" mandatory="true"/>
                        <param name="user_id" group="action.scheduler.23" label="action.scheduler.17" description="action.scheduler.17d" type="string" mandatory="true" default=""/>
                        <param name="repository_id" group="action.scheduler.23" replicationGroup="group2" label="action.scheduler.4" description="action.scheduler.4d" type="select" choices="" mandatory="true"/>
                        <param name="action_name" group="action.scheduler.24" label="action.scheduler.1" description="action.scheduler.1d" type="select" choices="json_list:list_all_plugins_actions" mandatory="true"/>
                        <param name="param_name" group="action.scheduler.24" replicationGroup="group1" label="action.scheduler.6" description="action.scheduler.6d" type="string" mandatory="false"/>
                        <param name="param_value" group="action.scheduler.24" replicationGroup="group1" label="action.scheduler.7" description="action.scheduler.7d" type="string" mandatory="false"/>
                    </standardFormDefinition>
                    <serverCallback methodName="handleTasks" developerComment="Create a new task by posting parameters">
                        <input_param description="All parameters generated by the FormManager (label, schedule, user_id, repository_id, action_name, one or more param_name / param_value)" name="FORM_DATA"
                                     type="FORM_DATA"/>
                    </serverCallback>
                </processing>
            </action>
            <action name="scheduler_runTask">
                <gui text="action.scheduler.16" title="action.scheduler.15d" iconClass="icon-play" src="scheduler/22/task_run.png" hasAccessKey="false">
                    <context selection="true" dir="" recycle="hidden" allowedMimes="scheduler_zone"
                             actionBar="true" contextMenu="true" infoPanel="true"
                             actionBarGroup="get"/>
                    <selectionContext dir="false" behaviour="hidden" file="true" recycle="false" unique="true" allowedMimes="scheduler_task"/>
                </gui>
                <processing>
                    <clientCallback prepareModal="true"><![CDATA[
                        var userSelection;
                        if(window.actionArguments && window.actionArguments.length){
                            userSelection = window.actionArguments[0];
                        }else{
                            userSelection =  pydio.getUserSelection();
                        }
                        var taskId = getBaseName(userSelection.getUniqueNode().getPath());
                        var connexion = new Connexion();
                        connexion.setParameters(new Hash({
                            get_action:'scheduler_runTask',
                            task_id:taskId
                        }));
                        connexion.onComplete = function(transport){
                            PydioApi.getClient().parseXmlMessage(transport.responseXML);
                        };
                        connexion.sendAsync();
                    ]]></clientCallback>
                    <serverCallback methodName="switchAction" developerComment="Force running a specific task">
                        <input_param description="The id of the task to run" name="task_id" type="string" mandatory="true"/>
                    </serverCallback>
                </processing>
            </action>
            <action name="scheduler_editTask">
                <gui text="action.scheduler.10" title="action.scheduler.11" iconClass="icon-edit" src="scheduler/ICON_SIZE/task.png" hasAccessKey="false">
                    <context selection="true" dir="" recycle="hidden" allowedMimes="scheduler_zone"
                             actionBar="true" contextMenu="true" infoPanel="true"
                             actionBarGroup="get"/>
                    <selectionContext dir="false" file="true" behaviour="hidden" recycle="false" unique="true" allowedMimes="scheduler_task"/>
                </gui>
                <processing>
                    <clientCallback><![CDATA[
                        var userSelection;
                        if(window.actionArguments && window.actionArguments.length){
                            userSelection = window.actionArguments[0];
                        }else{
                            userSelection =  pydio.getUserSelection();
                        }
                        pydio.getController().fireAction('scheduler_addTask', userSelection.getUniqueNode());
                    ]]></clientCallback>
                </processing>
            </action>
            <action name="scheduler_removeTask">
                <gui text="action.scheduler.19" title="action.scheduler.12" iconClass="icon-trash" src="scheduler/22/task_delete.png" hasAccessKey="false">
                    <context selection="true" dir="" recycle="hidden" allowedMimes="scheduler_zone"
                             actionBar="true" contextMenu="true" infoPanel="true"
                             actionBarGroup="get"/>
                    <selectionContext dir="false" file="true" behaviour="hidden" recycle="false" unique="true" allowedMimes="scheduler_task"/>
                </gui>
                <processing>
                    <clientCallback><![CDATA[
                        var userSelection;
                        if(window.actionArguments && window.actionArguments.length){
                            userSelection = window.actionArguments[0];
                        }else{
                            userSelection =  pydio.getUserSelection();
                        }
                        var conn = new Connexion();
                        conn.setParameters($H({ get_action : 'scheduler_removeTask', task_id: getBaseName(userSelection.getUniqueNode().getPath()) }));
                        conn.onComplete = function(transport){
                            PydioApi.getClient().parseXmlMessage(transport.responseXML);
                         };
                        conn.sendAsync();

                    ]]></clientCallback>
                    <serverCallback methodName="handleTasks" developerComment="Remove a given task from scheduler">
                        <input_param description="Id of the task to delete" name="task_id" type="string" mandatory="true"/>
                    </serverCallback>
                </processing>
            </action>
            <action name="scheduler_fakeLongTask">
                <processing>
                    <serverCallback methodName="fakeLongTask" developerComment="Launch a fake long task."/>
                </processing>
            </action>
        </actions>
        <hooks>
            <serverCallback methodName="placeConfigNode" hookName="ajxp_conf.list_config_nodes"/>
            <serverCallback methodName="placeConfigNode" hookName="admin.list_config_nodes"/>
        </hooks>
    </registry_contributions>
    <class_definition filename="plugins/action.scheduler/class.AjxpScheduler.php" classname="AjxpScheduler"/>
    <dependencies>
        <activePlugin pluginName="access.ajxp_conf|access.ajxp_admin"/>
    </dependencies>
</ajxp_plugin>
