#!/usr/bin/env node
//# vi: ft=javascript

var fs = require('fs');
var path = require('path');

var _ = require('lodash');
var express = require('express');
var handlebars = require('handlebars');

var app = express();
var staticHandler = express['static'].bind(express);

function toInt(num) {
  return parseInt(num, 10);
}

app.use((function log() {
  var text = '{{date}} {{req.method}} {{req.url}}';
  var logTemplate = handlebars.compile(text);

  return function (req, res, next) {
    console.log(logTemplate({date: new Date().toISOString(), req: req}));
    next();
  };
}()));

function renderError(res, err) {
  console.error(err.toString());
  res.writeHead(500, {'Content-Type': 'text/plain'});
  res.send(err.toString());
}

function pathToFile() {
  return path.normalize(
    path.join.apply(null, [__dirname, '..'].concat(_.toArray(arguments)))
  );
}

function index(req, res) {
  var indexFile = pathToFile('assets', 'index.html');

  function compileServe(err, text) {
    if (err) {
      renderError(res, err);
      return;
    }
    var tmpl = handlebars.compile(text);
    res.send(tmpl());
  }

  fs.readFile(indexFile, {encoding: 'utf8'}, compileServe);
}

app.get('/', index);

function getMarkdownFiles(cb) {
  fs.readdir(pathToFile('data', 'slide'), function (err, files) {
    if (err) {
      return cb(err);
    }
    files.sort();
    var markdownFiles = _.filter(files, function (file) {
      return /\.md$/.test(file);
    });
    cb(null, markdownFiles);
  });
}

app.get('/slides', function showHandler(req, res) {
  getMarkdownFiles(function (err, files) {
    if (err) {
      return renderError(res, err);
    }

    res.send(_.map(files, function (file, index) {
      return {id: index + 1};
    }));
  });
});

app.get(/slide\/(\d+)/, function showHandler(req, res, next) {
  if (!req.xhr) {
    index(req, res);
    return;
  }

  var slideIndex = toInt(req.params[0]);

  getMarkdownFiles(function (err, files) {
    if (err) {
      return renderError(res, err);
    }
    if (slideIndex > files.length) {
      return next();
    }

    var markdownFile = files[slideIndex - 1];
    var markdownPath = pathToFile('data', 'slide', markdownFile);
    fs.readFile(markdownPath, {encoding: 'utf8'}, function (err, content) {
      if (err) {
        return renderError(res, err);
      }
      res.send({id: toInt(slideIndex), copy: content});
    });
  });
});

app.use('/data', staticHandler('data'));
app.use('/vendor', staticHandler('vendor'));
app.use('/static', staticHandler('static'));

app.listen(8000);
