const express = require('express')
const router = express.Router()
const db = require('qmi-cloud-common/mongo');
const config = require('qmi-cloud-common/config');
const passport = require('../passport');
const fs = require('fs-extra');
const cli = require('qmi-cloud-common/cli');
const barracuda = require('qmi-cloud-common/barracuda');

async function asyncForEach(array, callback) {
  for (let index = 0; index < array.length; index++) {
      await callback(array[index], index, array);
  }
}

import { queues, TF_APPLY_QUEUE, TF_APPLY_QSEOK_QUEUE, TF_DESTROY_QUEUE, STOP_CONTAINER_QUEUE } from 'qmi-cloud-common/queues';

/**
 * @swagger
 * /users:
 *    get:
 *      description: Get all users
 *      summary: Get all users
 *      tags:
 *        - admin
 *      parameters:
 *        - name: filter
 *          in: query
 *          required: false
 *          type: object
 *          content:
 *            application/json: 
 *              schema:
 *                type: object
 *      produces:
 *        - application/json
 *      responses:
 *        200:
 *          description: User
 */
router.get('/', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {
  try {
    const filter = req.query.filter? JSON.parse(req.query.filter) : {};
    const result = await db.user.get(filter);
    return res.json(result);
  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/me:
 *    get:
 *      description: Get profile logged-in user
 *      summary: Get logged-in user
 *      produces:
 *        - application/json
 *      responses:
 *        200:
 *          description: User
 */
router.get('/me', passport.ensureAuthenticated, async (req, res, next) => {
  try {
    const result = await db.user.getById(req.user._id);
    return res.json(result);
  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}:
 *    get:
 *      description: Get profile for an user
 *      summary: Get profile for an user
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *      produces:
 *        - application/json
 *      responses:
 *        200:
 *          description: User
 */
router.get('/:userId', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {
    const userId = req.params.userId === 'me'? req.user._id : req.params.userId;
    const result = await db.user.getById(userId);
    return res.json(result);
  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}:
 *    put:
 *      description: Update profile for an user
 *      summary: Update profile for an user
 *      tags:
 *        - admin
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - in: body
 *          name: body
 *          description: User object
 *          required: true
 *      produces:
 *        - application/json
 *      responses:
 *        200:
 *          description: User
 */
router.put('/:userId', passport.ensureAuthenticatedAndAdmin, async (req, res, next) => {

  try {
    const userId = req.params.userId === 'me'? req.user._id : req.params.userId;
    const result = await db.user.update(userId, req.body);
    return res.json(result);
  } catch (error) {
    next(error);
  }
});


/**
 * @swagger
 * /users/{userId}/provisions:
 *    post:
 *      description: Start a new Terraform provision
 *      summary: Start a new Terraform provision
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *      requestBody:
 *        required: true
 *        content:
 *          application/json:
 *            schema:
 *              type: object
 *              properties:
 *                scenario:
 *                  type: string
 *                description:
 *                  type: string
 *                vmImage:
 *                  type: object
 *                  properties:
 *                    vm1:
 *                      type: object
 *                      properties:
 *                        vmType:
 *                          type: string
 *                        version:
 *                          type: object
 *                          properties:
 *                            name:
 *                              type: string
 *                            image:
 *                              type: string
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Scenario not found
 *        400:
 *          description: Invalid vmImage
 */
router.post('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {
    
    const userId = req.params.userId === 'me'? req.user._id : req.params.userId;
    req.body.user = userId;
    const scenarioSource = await db.scenario.getOne({name: req.body.scenario});

    if (!scenarioSource) {
      return res.status(404).json({"msg": "Scenario not found "});
    }

    const filterProvisions = {"user": userId, "isDestroyed": false, "isDeleted": false, "scenario": scenarioSource.name };
    const result = await db.provision.get(filterProvisions);

    if ( scenarioSource.numSimultaneousProvisions && result.total >= scenarioSource.numSimultaneousProvisions ) {
      return res.status(400).json({"msg": "Number of simultaneous provisions reached for this scenario: " + scenarioSource.numSimultaneousProvisions});
    }

    //if (!req.body.vmImage || !req.body.vmImage.vm1 || !req.body.vmImage.vm1.vmType ) {
    //  return res.status(400).json({"msg": "Invalid vmImage"});
    //}
    
    req.body.scenarioVersion = scenarioSource.version;

    if ( req.body.scheduleData && req.body.scheduleData.is24x7 !== undefined ) {
      const schedule = await db.schedule.add(req.body.scheduleData);
      req.body.schedule = schedule._id;
    }

    req.body.terraformImage = config.DOCKERIMAGE_TERRAFORM;
    
    if ( req.body.scenario.indexOf('azqmi-qdi') !== -1 ) {
      req.body.version = config.PROVISION_VERSION;
    }
    
    
    const provision = await db.provision.add(req.body);
    
    
    if ( provision.scenario === "azqmi-qseok" ){
      queues[TF_APPLY_QSEOK_QUEUE].add("tf_apply_qseok_job", {
        scenario: req.body.scenario,
        vmType: req.body.vmType || null,
        nodeCount: req.body.nodeCount,
        id: provision._id,
        user: req.user,
        _scenario: scenarioSource
      });
    } else {
      queues[TF_APPLY_QUEUE].add("tf_apply_job", {
        scenario: req.body.scenario,
        vmType: req.body.vmType,
        nodeCount: req.body.nodeCount,
        id: provision._id,
        user: req.user,
        _scenario: scenarioSource
      });
    }

    return res.status(200).json(provision);

  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}:
 *    get:
 *      description: Get provision details
 *      summary: Get provision details
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      produces:
 *        - application/json
 *      responses:
 *        200:
 *          description: Provision
 */
 router.get('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  
  try {
    let provision = await db.provision.getById(req.params.id);
    return res.json(provision);
  } catch (error) {
    next(error);
  }
  
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}:
 *    put:
 *      description: Update Provision by ID
 *      summary: Update Provision by ID
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *        - in: body
 *          name: body
 *          description: Provision object
 *          required: true
 *      produces:
 *        - application/json
 *      responses:
 *        200:
 *          description: Provision
 */
router.put('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  let provision = await db.provision.getById(req.params.id);
  if (!provision){
    return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
  }

  try {
    
    let schedule;
    var msg = "";
    if ( req.body.scheduleData ) {

      if ( req.body.scheduleData._id ) {
        schedule = await db.schedule.update(req.body.scheduleData._id, req.body.scheduleData);
      } else {
        schedule = await db.schedule.add(req.body.scheduleData);
      }
      var tagsEdit = {
        "24x7": schedule.is24x7? " " : false,
        "StartupTime": (schedule.isStartupTimeEnable && !schedule.is24x7 && schedule.utcTagStartupTime)? schedule.utcTagStartupTime : false,
        "ShutdownTime": (!schedule.is24x7 && schedule.utcTagShutdownTime)? schedule.utcTagShutdownTime : false
      }
      cli.updateVmsTags(provision._id, tagsEdit);

    }

    let patch = {};
    if ( req.body.user ) {
      patch.user = req.body.user;
      msg += ` - new user: ${req.body.user}`;
    }
    if ( schedule ) {
      patch.schedule = schedule._id;
      msg += ` - new schedule: ${schedule._id}`;
    }

    let result = {
      provision: await db.provision.update(provision._id, patch),
      event: await db.event.updateMany({"provision": provision._id}, {"user": req.body.user})
    }

    db.event.add({ user: provision.user._id, provision: provision._id, type: 'provision.update', message: msg });

    return res.json(result);

  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}:
 *    delete:
 *      description: Delete Provision by ID 
 *      summary: Delete a Terraform Provision by ID
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Not found
 *        
 */
router.delete('/:userId/provisions/:id', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
    try {

      const provision = await db.provision.getById(req.params.id);
      if (!provision){
        return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
      }
      //var delDest = provision.destroy._id;
      //if ( provision.destroy ) {
      //  delDest = await db.destroy.del(provision.destroy._id);
      //}
      const delProv = await db.provision.update(req.params.id, {"isDeleted": true});

      //Move folder 
      if (fs.existsSync(`/provisions/${provision.scenario}_${req.params.id}`)) {
        fs.moveSync(`/provisions/${provision.scenario}_${req.params.id}`, `/provisions/deleted/${provision.scenario}_${req.params.id}`, { overwrite: true })
      }

      db.event.add({ user: provision.user._id, provision: provision._id, type: 'provision.delete-history' });

      return res.json({"provision": delProv, "destroy": delProv.destroy});
    } catch (error) {
      next(error);
    }
  });

/**
 * @swagger
 * /users/{userId}/provisions/{id}/barracuda:
 *    get:
 *      description: Barracuda - get details and provision status
 *      summary: Barracuda - get details and provision status
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Not found
 *        
 */
 router.get('/:userId/provisions/:id/barracuda', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {

    let provision = await db.provision.getById(req.params.id);
    if (!provision){
      return res.status(404).json({"msg": "Not found provision with id "+req.params.id});
    }

    if ( !provision.barracudaAppId ) {
      console.log(`APIUser# Provision (${req.params.id}) does not have a barracudaAppId value!`);
      return res.status(404).json({"msg": "Not found Barracuda App for this provision"});
    }

    var app = await barracuda.getApp(provision);
    return res.json(app);
    
  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}/barracuda:
 *    post:
 *      description: Barracuda - give a provision external access
 *      summary: Barracuda - give a provision external access
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Not found
 *        
 */
 router.post('/:userId/provisions/:id/barracuda', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {

    let provision = await db.provision.getById(req.params.id);
    if (!provision){
      return res.status(404).json({"msg": "Not found provision with id "+req.params.id});
    }

    if ( !provision.barracudaAzureFqdn ) {
      console.log(`APIUser# Provision (${req.params.id}) does not have a barracudaAzureFqdn value!`);
      return res.json(provision);
    }

    if ( provision.barracudaAppId ) {
      console.log(`APIUser# Provision (${req.params.id}) already have a Barracuda App (${provision.barracudaAppId})!`);
      return res.json(provision);
    }

    console.log(`APIUser# Calling Barracuda service to create App and DNS CName for provision (${provision._id})`);
    barracuda.createApp(provision);
     
    return res.json(provision);
    
  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}/barracuda:
 *    delete:
 *      description: Barracuda - delete a provision external access
 *      summary: Barracuda - delete a provision external access
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Not found
 *        
 */
 router.delete('/:userId/provisions/:id/barracuda', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {

    let provision = await db.provision.getById(req.params.id);
    if (!provision){
      return res.status(404).json({"msg": "Not found provision with id "+req.params.id});
    }

    if ( !provision.barracudaAppId ) {
      console.log(`APIUser# Provision (${req.params.id}) does not have a barracudaAppId value!`);
      return res.json({});
    }

    console.log(`APIUser# Calling Barracuda service to delete App and DNS CName for provision (${provision._id})`);
    barracuda.deleteApp(provision);
  
     
    return res.json(provision);
    
  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}/abort:
 *    post:
 *      description: Abort provision
 *      summary: Abort provision
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Not found
 *        
 */
 router.post('/:userId/provisions/:id/abort', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {

    let provision = await db.provision.getById(req.params.id);
    if (!provision){
      return res.status(404).json({"msg": "Not found provision with id "+req.params.id});
    }

    queues[STOP_CONTAINER_QUEUE].add("tf_abort_apply_job", {
      provId: provision._id,
      user: req.user
    });

    return res.json({"status": "aborting"});
    
  } catch (error) {
    next(error);
  }
});


/**
 * @swagger
 * /users/{userId}/provisions/{id}/deallocatevms:
 *    post:
 *      description: Stop all VMs for this provision
 *      summary: Stop all VMs for this provision
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Not found
 *        
 */
router.post('/:userId/provisions/:id/deallocatevms', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {

    let provision = await db.provision.getById(req.params.id);
    if (!provision){
      return res.status(404).json({"msg": "Not found provision with id "+req.params.id});
    }
    
    //Set DivvyTags according to Schedule
    if ( provision.schedule && req.body.isStartupTimeEnable !== undefined ) {
      console.log("APIUser# Set DivvyTags according to schedule");
      var schedule = await db.schedule.update(provision.schedule._id, { "isStartupTimeEnable": req.body.isStartupTimeEnable });
      var tagsEdit = {
        "24x7": schedule.is24x7? " " : false,
        "StartupTime": (schedule.isStartupTimeEnable && !schedule.is24x7 && schedule.utcTagStartupTime)? schedule.utcTagStartupTime : false,
        "ShutdownTime": (!schedule.is24x7 && schedule.utcTagShutdownTime)? schedule.utcTagShutdownTime : false
      }
      cli.updateVmsTags(provision._id, tagsEdit);   
    }

    cli.deallocate(provision._id);
    
    return res.json({"statusVms": "Stopping"});

  } catch (error) {
    db.provision.update(req.params.id, {"statusVms": "Error_Stopping"});
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}/startvms:
 *    post:
 *      description: Start all VMs for this provision
 *      summary: Start all VMs for this provision
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Not found
 *        
 */
router.post('/:userId/provisions/:id/startvms', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {

    let provision = await db.provision.getById(req.params.id);
    if (!provision){
      return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
    }

    //Re-enable DivvyTags according to schedule
    if ( provision.schedule ) {

      let schedule = await db.schedule.getById(provision.schedule._id);

      console.log("APIUser# Re-enabling DivvyTags according to schedule");
      var tagsEdit = {
          "24x7": schedule.is24x7? " " : false,
          "StartupTime": (schedule.isStartupTimeEnable && !schedule.is24x7 && schedule.utcTagStartupTime)? schedule.utcTagStartupTime : false,
          "ShutdownTime": (!schedule.is24x7 && schedule.utcTagShutdownTime)? schedule.utcTagShutdownTime : false
      }
      cli.updateVmsTags(provision._id, tagsEdit);
    }

    cli.start(provision._id);
    
    return res.json({"statusVms": "Starting"});

  } catch (error) {
    db.provision.update(req.params.id, {"statusVms": "Error_Starting"});
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}/extend:
 *    post:
 *      description: Extend this provision Running more time
 *      summary: Extend this provision Running more time
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Not found
 *        
 */
router.post('/:userId/provisions/:id/extend', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {

    let provision = await db.provision.getById(req.params.id);
    if (!provision){
      return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
    }
    
    /*if ( provision.countExtend === 5 ) {
      return res.status(200).json({"msg": "You have reached the limit for the number of times to extend the Running VMs period."});
    }*/

    let timeRunning = db.utils.getNewTimeRunning(provision);
    let countExtend = db.utils.getNewCountExtend(provision);
    provision = await db.provision.update(req.params.id, {"runningFrom":new Date(), "timeRunning": timeRunning, "countExtend": countExtend, "pendingNextAction": undefined});
    
    console.log(`APIUser# Extending running period fo provision (${provision._id}), new total extends: ${countExtend}`);

    return res.json(provision);

  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}/destroy:
 *    post:
 *      description: Destroy a Terraform Provision
 *      summary: Destroy a Terraform Provision
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: Provision
 *        404:
 *          description: Not found
 *        
 */
router.post('/:userId/provisions/:id/destroy', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  
  try {
    const userId = req.params.userId === 'me'? req.user._id : req.params.userId;
    let provision = await db.provision.getById(req.params.id);
    if (!provision){
      return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
    }

    console.log(`APIUser# Queueing destroy provision: ${provision._id}`);
    const destroyJob = await db.destroy.add({ "user": userId });
    provision = await db.provision.update(req.params.id, {"destroy": destroyJob._id});
    const scenarioSource = await db.scenario.getOne({name: provision.scenario});

    queues[TF_DESTROY_QUEUE].add("tf_destroy_job", {
      scenario: provision.scenario,
      provId: provision._id,
      user: req.user,
      id: destroyJob._id,
      _scenario: scenarioSource
    });

    //Check children provisions
    let children = await db.provision.get({ "parent": provision._id, "isDestroyed": false, "isDeleted": false });
    
    if (children.results.length > 0 ) {
      await asyncForEach(children.results, async function(child)  {
          console.log(`APIUser# Queueing destroy children provision: ${child._id}`);
          let destroyJobChild = await db.destroy.add({ "user": userId });
          await db.provision.update(child._id, {"destroy": destroyJobChild._id});
          let scenarioSourceChild = await db.scenario.getOne({name: child.scenario});

          queues[TF_DESTROY_QUEUE].add("tf_destroy_job", {
            scenario: child.scenario,
            provId: child._id,
            user: req.user,
            id: destroyJobChild._id,
            _scenario: scenarioSourceChild
          });
      })
    }
    return res.status(200).json(provision);

  } catch (error) {
    return res.status(error.output.statusCode).json({"err":error});
  }
});

/**
 * @swagger
 * /users/{userId}/provisions:
 *    get:
 *      description: Get all Provisions for an User
 *      summary: Get all Provisions for an User
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: JSON Array
 */
router.get('/:userId/provisions', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {

  try {
    const userId = req.params.userId === 'me'? req.user._id : req.params.userId;
    const filter = {"user": userId, "isDeleted": false};
    const result = await db.provision.get(filter);
    return res.json(result);
  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/events:
 *    get:
 *      description: Get all Events for an User
 *      summary: Get all Events for an User
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: JSON Array
 */
router.get('/:userId/events', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {

  try {
    const userId = req.params.userId === 'me'? req.user._id : req.params.userId;
    const result = await db.event.get({"user": userId});
    return res.json(result);
  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/provisions/{id}/events:
 *    get:
 *      description: Get all Events for an User and Provision
 *      summary: Get all Events for an User and Provision
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *        - name: id
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: JSON Array
 */
router.get('/:userId/provisions/:id/events', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {

  try {
    const userId = req.params.userId === 'me'? req.user._id : req.params.userId;
    const result = await db.event.get({"user": userId, "provision": req.params.id});
    return res.json(result);
  } catch (error) {
    next(error);
  }
});

/**
 * @swagger
 * /users/{userId}/scenarios:
 *    get:
 *      description: Get all Provisions for an User
 *      summary: Get all Provisions for an User
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: JSON Array
 */
router.get('/:userId/scenarios', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
  try {
    let filter = {};
    if (req.user.role === "user") {
      filter.isAdminOnly = false;
    }
    filter.isDisabled = filter.isDisabled || false;
    var result = await db.scenario.get(filter);
    if (req.user.role === "user") {
      result.results = result.results.filter( scenario => {
        let noAllowedUsers = !scenario.allowedUsers || scenario.allowedUsers.length === 0;
        if ( noAllowedUsers ) {
          return true;
        } else {
          let allowedUserIds = scenario.allowedUsers.map( u=> u._id.toString());
          return allowedUserIds.indexOf(req.user._id.toString()) !== -1;
        }
      });
    }
    return res.json(result);
    
  } catch (error) {
    next(error);
  }
});


/**
 * @swagger
 * /users/{userId}/destroyprovisions:
 *    get:
 *      description: Get all Destroy Provisions for an User
 *      summary: Get all Destroy Provisions for an User
 *      produces:
 *        - application/json
 *      parameters:
 *        - name: userId
 *          in: path
 *          type: string
 *          required: true
 *      responses:
 *        200:
 *          description: JSON Array
 */
router.get('/:userId/destroyprovisions', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {

  try {
    const userId = req.params.userId === 'me'? req.user._id : req.params.userId;
    const result = await db.destroy.get({"user": userId});
    return res.json(result);
  } catch (error) {
    next(error);
  }
});


module.exports = router;