const router = require('koa-router')()
const jwt = require('koa-jwt')

const log = require('../lib/log')
const Page = require('../models/page')
const User = require('../models/user')

router.post('/token-auth', function *(next) {
  const body = this.request.body

  if (!body.username || !body.password) {
    this.status = 400
    this.body = {
      error: 'User and/or password empty'
    }
    return
  }

  const query = User.where({ _id: body.username })

  try {
    var user = yield query.findOne()
  } catch (err) {
    log('Couldn\'t load user', err)
  }

  if (!user) {
    this.status = 400
    this.body = {
      error: 'User doesn\'t exist'
    }
    return
  }

  // Compare password with the one within the DB
  const isMatch = user.tryPassword(body.password)

  if (isMatch) {
    const token = jwt.sign(body, process.env.SESSION_SECRET, {
      expiresIn: 300
    })

    this.body = {
      token
    }

    return
  }

  this.status = 400

  this.body = {
    error: 'Wrong password'
  }

  yield next
})

router.post('/token-refresh', function *(next) {
  const token = this.request.body.token

  try {
    const decoded = jwt.verify(token, process.env.SESSION_SECRET)
  } catch (err) {
    this.status = 401
    this.body = { error: err }

    return
  }

  const query = User.where({ _id: decoded.username })

  try {
    var user = yield query.findOne()
  } catch (err) {
    log('Couldn\'t load user', err)
  }

  if (!user) {
    this.status = 401
    this.body = {
      error: 'User doesn\'t exist'
    }

    return
  }

  const isMatch = user.tryPassword(decoded.password)

  if (isMatch) {
    this.body = {
      token: jwt.sign(decoded, process.env.SESSION_SECRET, {
        expiresIn: 300
      })
    }

    return
  }

  this.status = 401

  this.body = {
    error: 'Wrong password'
  }

  console.log(decoded)
})

router.get('/pages', function *(next) {
  try {
    var pages = yield Page.find()
  } catch (err) {
    return log('Couldn\'t load pages', err)
  }

  var data = []

  for (var page in pages) {
    var attributes = pages[page].toObject()
    var id = attributes.id

    delete attributes.id
    delete attributes._id
    delete attributes.__v

    data.push({
      id,
      type: 'pages',
      attributes
    })
  }

  this.body = { data }
  yield next
})

router.get('/pages/:id', function *(next) {
  const query = Page.where({ _id: this.params.id })

  try {
    var page = yield query.findOne()
  } catch (err) {
    return log('Couldn\'t load page', err)
  }

  var attributes = page.toObject()
  var id = attributes.id

  delete attributes.id
  delete attributes._id
  delete attributes.__v

  this.body = {
    data: {
      id,
      type: 'page',
      attributes
    }
  }

  yield next
})

router.get('/users', function *(next) {
  try {
    var users = yield User.find()
  } catch (err) {
    return log('Couldn\'t load users', err)
  }

  var data = []

  for (var user in users) {
    const details = users[user].toObject()

    data.push({
      id: details._id,
      type: 'users',
      attributes: {
        email: details.email
      }
    })
  }

  this.body = { data }
  yield next
})

router.get('/users/:id', function *(next) {
  const query = User.where({ _id: this.params.id })

  try {
    var user = yield query.findOne()
  } catch (err) {
    return log('Couldn\'t load user', err)
  }

  var attributes = user.toObject()
  var id = attributes._id

  delete attributes._id
  delete attributes.__v
  delete attributes.password

  this.body = {
    data: {
      id,
      type: 'user',
      attributes
    }
  }

  yield next
})

module.exports = router

@@ -177,16 +177,396 @@
 user')%0A%0A
+function *getOne (type, _id) %7B%0A  const query = eval(type + '.where(%7B _id %7D)')%0A%0A  try %7B%0A    var item = yield query.findOne()%0A  %7D catch (err) %7B%0A    return log('Couldn%5C't load item', err)%0A  %7D%0A%0A  var attributes = item.toObject()%0A%0A  delete attributes._id%0A  delete attributes.__v%0A  delete attributes.password%0A%0A  return %7B%0A    id: _id,%0A    type: type.toLowerCase(),%0A    attributes%0A  %7D%0A%7D%0A%0A
 router.p
@@ -2736,383 +2736,68 @@
 %7B%0A  
-const query = Page.where(%7B _id: this.params.id %7D)%0A%0A  try %7B%0A    var page = yield query.findOne()%0A  %7D catch (err) %7B%0A    return log('Couldn%5C't load page', err)%0A  %7D%0A%0A  var attributes = page.toObject()%0A  var id = attributes.id%0A%0A  delete attributes.id%0A  delete attribute
+this.body = %7B%0A    data: yield getOne('Page', this.param
 s.
-_
 id
-%0A  delete attributes.__v%0A%0A  this.body = %7B%0A    data: %7B%0A      id,%0A      type: 'page',%0A      attributes%0A    %7D
+)
 %0A  %7D
@@ -3272,390 +3272,68 @@
 %7B%0A  
-const query = User.where(%7B _id: this.params.id %7D)%0A%0A  try %7B%0A    var user = yield query.findOne()%0A  %7D catch (err) %7B%0A    return log('Couldn%5C't load user', err)%0A  %7D%0A%0A  var attributes = user.toObject()%0A  var id = attributes._id%0A%0A  delete attributes._id%0A  delete attributes.__v%0A  delete attributes.password%0A%0A  this.body = %7B%0A    data: %7B%0A      id,%0A      type: 'user',%0A      attributes%0A    %7D
+this.body = %7B%0A    data: yield getOne('User', this.params.id)
 %0A  %7D

Use a single function