const express = require('express');
const router = express.Router(); // eslint-disable-line new-cap
const async = require('async');

const DeviceTypeModel = require('../models/device-type');
const authenticate = require('../middlewares/authenticate');
const authorise = require('../middlewares/authorise');
const resHelpers = require('./helpers/response-helpers');

router.use('/device-types', authenticate);

// Create device type
router.post('/device-types', authorise('admin'), (req, res) => {
  DeviceTypeModel.create(req.body, (err, deviceType) => {
    if (err && err.name && err.name === 'ValidationError') {
      return res.json(resHelpers.validationFail(
        'The device type could not be created. Check validation.',
        err.errors,
        req.body
      ));
    }

    if (err) {
      return res.json(resHelpers.error(err));
    }

    res.json(resHelpers.success(
      'The device type was created.',
      deviceType.toObject()
    ));
  });
});

// List device types
router.get('/device-types', (req, res) => {
  const page = req.query.page || 1;
  const limit = 20;

  async.parallel({
    total: function total(cb) {
      DeviceTypeModel.count(cb);
    },
    deviceTypes: function getDeviceTypes(cb) {
      DeviceTypeModel
        .find()
        .skip(limit * (page - 1))
        .limit(limit)
        .lean()
        .exec(cb);
    },
  }, (err, result) => {
    if (err) {
      return res.json(resHelpers.error('The query could not be executed.'));
    }

    res.json(resHelpers.success(
      'Device types were found.',
      result.deviceTypes,
      {
        paginate: {
          total: result.total,
          previous: ((page > 1) ? page - 1 : null),
          next: (((limit * page) < result.total) ? page + 1 : null),
        },
      }
    ));
  });
});

// Get device type
router.get('/device-types/:deviceType', (req, res) => {
  DeviceTypeModel.findById(req.params.deviceType, (err, deviceType) => {
    if (err) {
      return res.json(resHelpers.error('Device type information could not be found.'));
    }

    if (deviceType === null) {
      return res.json(resHelpers.fail(
        `No device type could be found with the ID ${req.params.deviceType}`
      ));
    }

    res.json(resHelpers.success(
      'The device type was found.',
      deviceType.toObject()
    ));
  });
});

// Update device type
router.put('/device-types/:deviceType', authorise('admin'), (req, res) => {
  DeviceTypeModel.findById(req.params.deviceType, (err, deviceType) => {
    if (err) {
      return res.json(resHelpers.error('The device type could not be updated.'));
    }

    if (deviceType === null) {
      return res.json(resHelpers.fail(
        `No device type could be found with the ID ${req.params.deviceType}`
      ));
    }

    deviceType.set(req.body).save((saveErr, updatedDeviceType) => {
      if (saveErr && saveErr.name && saveErr.name === 'ValidationError') {
        return res.json(resHelpers.validationFail(
          'The device type could not be updated. Check validation.',
          saveErr.errors,
          req.body
        ));
      }

      if (saveErr) {
        return res.json(resHelpers.error(saveErr));
      }

      res.json(resHelpers.success(
        'The device type was updated.',
        updatedDeviceType.toObject()
      ));
    });
  });
});

// Delete device type
router.delete('/device-types/:deviceType', authorise('admin'), (req, res) => {
  DeviceTypeModel.findByIdAndRemove(req.params.deviceType, err => {
    if (err) {
      return res.json(resHelpers.error('The device type could not be deleted.'));
    }

    res.json(resHelpers.success('The device type was deleted'));
  });
});

module.exports = router;

@@ -1030,16 +1030,41 @@
 s) =%3E %7B%0A
+  const %7B query %7D = req;%0A
   const 
@@ -1070,20 +1070,16 @@
  page = 
-req.
 query.pa
@@ -1106,16 +1106,484 @@
 it = 20;
+%0A  const filters = %7B%0A    name: query.name,%0A    developer: query.developer,%0A    deviceClass: query.deviceClass,%0A  %7D;%0A  const sort = query.sort %7C%7C 'name';%0A  const order = query.order && query.order === 'desc' ? -1 : 1;%0A%0A  const criteria = Object.keys(filters).reduce((prev, path) =%3E %7B%0A    if (filters%5Bpath%5D) %7B%0A      return Object.assign(%7B%7D, prev, %7B%0A        %5Bpath%5D: %7B%0A          $regex: new RegExp(filters%5Bpath%5D, 'i'),%0A        %7D,%0A      %7D);%0A    %7D%0A    return prev;%0A  %7D, %7B%7D);
 %0A%0A  asyn
@@ -1649,16 +1649,31 @@
 peModel.
+find(criteria).
 count(cb
@@ -1765,16 +1765,24 @@
   .find(
+criteria
 )%0A      
@@ -1831,16 +1831,68 @@
 (limit)%0A
+        .sort(%7B%0A          %5Bsort%5D: order,%0A        %7D)%0A
         
@@ -2040,32 +2040,200 @@
 ted.'));%0A    %7D%0A%0A
+    const pages = Math.ceil(result.total / limit);%0A%0A    if (pages %3E 0 && page %3E pages) %7B%0A      return res.json(resHelpers.error(%60Page $%7Bpage%7D does not exist%60));%0A    %7D%0A%0A
     res.json(res
@@ -2368,16 +2368,78 @@
 .total,%0A
+          pages,%0A          currentPage: pages %3E 0 ? page : 0,%0A
         
@@ -2448,16 +2448,20 @@
 previous
+Page
 : ((page
@@ -2500,16 +2500,20 @@
     next
+Page
 : (((lim

enable filtering