mongoose = require 'mongoose'
Id = mongoose.Types.ObjectId

crud = (router, modelName, filter = "", restriction = [])->
  Model = mongoose.model(modelName)

  # Read by ID
  router.get '/:id', (req, res, next)->
    if not restriction['read']? or restriction['read'](req, res)
      id = Id(req.params.id)
      Model.findById id, filter, (err, result)->
        if err or not result?
          res.status(400).send("#{modelName} not found")
        else
          res.json result
    else
      res.status(403).send("Forbidden")

  # Read by page
  router.get '/:page/:pageSize', (req, res, next)->
    if not restriction['read']? or restriction['read'](req, res)
      page = req.params.page
      pageSize = req.params.pageSize
      Model.find({}, filter).skip((page-1)*pageSize).limit(pageSize).exec (err, results)->
        if err
          res.status(500).render 'error',
            error: err
        else
          res.json results
    else
      res.status(403).send("Forbidden")

  # Create
  router.post '/', (req, res, next)->
    if not restriction['create']? or restriction['create'](req, res)
      obj = new Model req.body
      obj.save (err)->
        if err
          res.status(500).render 'error',
            error: err
        else
          res.json obj
    else
      res.status(403).send("Forbidden")

  # Edit by ID
  router.put '/:id', (req, res, next)->
    if not restriction['edit']? or restriction['edit'](req, res)
      id = Id(req.params.id)
      Model.findById id, filter, (err, result)->
        if err
          res.status(500).render 'error',
            error: err
        else
          result.update req.body, (err, ans)->
            if err
              res.status(500).render 'error',
                error: err
            else
              Model.findById id, filter, (err, result)->
                if err
                  res.status(500).render 'error',
                    error: err
                else
                  res.json(result)
    else
      res.status(403).send("Forbidden")

  # Delete by ID
  router.delete '/:id', (req, res, next)->
    if not restriction['delete']? or restriction['delete'](req, res)
      id = Id(req.params.id)
      Model.findById id, filter, (err, result)->
        result.remove (err, ans)->
          if err
            res.status(500).render 'error',
              error: err
          else
            res.send ans
    else
      res.status(403).send("Forbidden")

module.exports = crud

