/** @module root/router */
'use strict';
// vim: set ts=2 sw=2 et tw=80:

const fs = require('fs');
const express = require('express');
const router = express.Router();

let id = 1;

function nextId(favs) {
  while (favs.some((newId => e => e._id == newId)(++id)));
  return id;
}

function createFav(req, res) {
  if (!req.body.name || !req.body.dataURL) {
    res.writeHead(400, { 'Content-Type': 'text/plain' });
    res.end('Bad create form parameters');
    return;
  }

  const favourite = {
    _id: req.body._id ? req.body._id : nextId(req.app.locals.favourites),
    name: req.body.name,
    dataURL: req.body.dataURL,
    bookmarked: req.body.bookmarked,
  };

  req.app.locals.favourites.push(favourite);
  req.app.locals.writeFavs(() => {
    res.status = 201;
    renderFav(req, res, favourite, false);
  });
}

router.post('/', createFav);

function renderFav(req, res, favs, list = true) {
  if (req.accepts('html')) {
    let ctx;
    if (list) {
      const f = [];
      for (const e of favs) {
        f.push(Object.assign({
          b: e.bookmarked === 'true' || e.bookmarked === true
        }, e));
      }
      ctx = {favs: f};
    } else {
      ctx = Object.assign({
        b: favs.bookmarked === 'true' || favs.bookmarked === true
      }, favs);
    }

    res.render(list ? 'favourites.dust' : 'favourite.dust', ctx);
  } else if (req.accepts('json')) {
    res.json(favs);
  } else {
    res.writeHead(406);
    res.end();
  }
}

router.get('/', (req, res) => {
  renderFav(req, res, req.app.locals.favourites);
});

router.get('/search', (req, res) => {
  const filtered = req.app.locals.favourites.filter(e => {
    for (const k in req.query) {
      if (k != 'dataURL' && k != '_method' && req.query[k] != e[k]) {
        return false;
      }
    }
    return true;
  });

  renderFav(req, res, filtered);
});

router.get('/:id', (req, res) => {
  const fav = req.app.locals.favourites
    .filter(e => e._id == req.params.id)[0];
  if (fav) {
    renderFav(req, res, fav, false);
  } else {
    res.writeHead(404, {'Content-Type': 'text/plain'});
    res.end('Not found');
  }
});

function handleUpdate(partial = false) {
  return (req, res) => {
    const edit = req.app.locals.favourites
      .find(e => e._id == req.params.id);

    if (!edit) {
      createFav(req, res);
    } else {
      for (const key of ['dataURL', 'name']) {
        if (req.body[key]) {
          edit[key] = req.body[key];
        } else if (!partial) {
          res.writeHead(400, { 'Content-Type': 'text/plain' });
          res.end('Bad PUT form parameters');
          return;
        }
      }

      if (req.body.bookmarked !== undefined) {
        edit.bookmarked = req.body.bookmarked;
      }
      req.app.locals.writeFavs(() => {
        res.status = 200;
        renderFav(req, res, edit, false);
      });
    }
  };
}

router.put('/:id', handleUpdate());
router.patch('/:id', handleUpdate(true));


router.delete('/:id', (req, res) => {
  let idx = -1;
  for (let i = 0; i < req.app.locals.favourites.length; i++) {
    if (req.app.locals.favourites[i]._id == req.params.id) {
      idx = i;
      break;
    }
  }

  if (idx == -1) {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Favourite not found');
    return;
  } else {
    req.app.locals.favourites.splice(idx, 1);
    req.app.locals.writeFavs(() => {
      res.format({
        json: () => res.writeHead(204),
        html: () => res.writeHead(302, { 'Location': '/favorites' })
      });
      res.end();
    });
  }
});

router.put('/:id/bookmarked', (req, res) => {
  const edit = req.app.locals.favourites
    .find(e => e._id == req.params.id);

  if (!edit) {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Favourite to bookmark not found');
  } else if (!req.body.bookmarked) {
    res.writeHead(400, { 'Content-Type': 'text/plain' });
    res.end('Bad PUT bookmark form parameters');
  } else {
    edit.bookmarked = req.body.bookmarked;
    req.app.locals.writeFavs(() => {
      res.status = 200;
      renderFav(req, res, edit, false);
    });
  }
});

/** router for /root */
module.exports = router;
