define(['context', 'core/logger', 'i18n', 'taoQtiTest/runner/config/states', 'taoQtiTest/runner/services/sequenceStore', 'taoTests/runner/plugin'], function (context, loggerFactory, __, states, sequenceStore, pluginFactory) { 'use strict';

    context = context && Object.prototype.hasOwnProperty.call(context, 'default') ? context['default'] : context;
    loggerFactory = loggerFactory && Object.prototype.hasOwnProperty.call(loggerFactory, 'default') ? loggerFactory['default'] : loggerFactory;
    __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
    states = states && Object.prototype.hasOwnProperty.call(states, 'default') ? states['default'] : states;
    pluginFactory = pluginFactory && Object.prototype.hasOwnProperty.call(pluginFactory, 'default') ? pluginFactory['default'] : pluginFactory;

    /**
     * This program 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; under version 2
     * of the License (non-upgradable).
     *
     * This program 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 this program; if not, write to the Free Software
     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     *
     * Copyright (c) 2023 (original work) Open Assessment Technologies SA ;
     */
    const logger = loggerFactory('taoQtiTest/runner/plugins/controls/session/preventConcurrency');
    const FEATURE_FLAG = 'FEATURE_FLAG_PAUSE_CONCURRENT_SESSIONS';

    /**
     * Test Runner Control Plugin : detect concurrent deliveries launched from the same user session.
     */
    var preventConcurrency = pluginFactory({
      name: 'preventConcurrency',
      /**
       * Initializes the plugin (called during runner's init)
       */
      init() {
        const testRunner = this.getTestRunner();
        const options = testRunner.getOptions();
        const skipPausedAssessmentDialog = !!options.skipPausedAssessmentDialog;
        return Promise.all([sequenceStore.getSequenceNumber(testRunner), sequenceStore.getSequenceStore()]).then(_ref => {
          let [sequenceNumber, sequenceStore] = _ref;
          return sequenceStore.setSequenceNumber(sequenceNumber).then(() => {
            testRunner.on('tick', () => {
              if (context.featureFlags[FEATURE_FLAG]) {
                return sequenceStore.getSequenceNumber().then(lastSequenceNumber => {
                  if (lastSequenceNumber !== sequenceNumber) {
                    testRunner.off('tick');
                    testRunner.trigger('disabletools');
                    testRunner.trigger('disablenav');
                    testRunner.trigger('disableitem');
                    testRunner.trigger('concurrency');
                    return Promise.reject();
                  }
                });
              }
            }).on('concurrency', () => {
              logger.warn(`The sequence number has changed. Was another delivery opened in the same browser?`);
              testRunner.trigger('leave', {
                code: states.testSession.suspended,
                message: __('A concurrent delivery has been detected. Please use the last open session. The present window can be closed.'),
                skipExitMessage: skipPausedAssessmentDialog
              });
            });
          });
        });
      }
    });

    return preventConcurrency;

});
