/**
 * This module contains some common helpers shared between middlewares
 */

var mime = require('mime');
var log = require('../logger').create('web-server');

var PromiseContainer = function() {
  var promise;

  this.then = function(success, error) {
    return promise.then(success, error);
  };

  this.set = function(newPromise) {
    promise = newPromise;
  };
};


var serve404 = function(response, path) {
  log.warn('404: ' + path);
  response.writeHead(404);
  return response.end('NOT FOUND');
};


var createServeFile = function(fs, directory) {
  var cache = Object.create(null);

  return function(filepath, response, transform, content) {
    var responseData;

    if (directory) {
      filepath = directory + filepath;
    }

    if (!content && cache[filepath]) {
      content = cache[filepath];
    }

    // serve from cache
    if (content) {
      response.setHeader('Content-Type', mime.lookup(filepath, 'text/plain'));

      // call custom transform fn to transform the data
      responseData = transform && transform(content) || content;

      response.writeHead(200);

      log.debug('serving (cached): ' + filepath);
      return response.end(responseData);
    }

    return fs.readFile(filepath, function(error, data) {
      if (error) {
        return serve404(response, filepath);
      }

      cache[filepath] = data.toString();

      response.setHeader('Content-Type', mime.lookup(filepath, 'text/plain'));

      // call custom transform fn to transform the data
      responseData = transform && transform(data.toString()) || data;

      response.writeHead(200);

      log.debug('serving: ' + filepath);
      return response.end(responseData);
    });
  };
};


var setNoCacheHeaders = function(response) {
  response.setHeader('Cache-Control', 'no-cache');
  response.setHeader('Pragma', 'no-cache');
  response.setHeader('Expires', (new Date(0)).toString());
};


var setHeavyCacheHeaders = function(response) {
  response.setHeader('Cache-Control', ['public', 'max-age=31536000']);
};


// PUBLIC API
exports.PromiseContainer = PromiseContainer;
exports.createServeFile = createServeFile;
exports.setNoCacheHeaders = setNoCacheHeaders;
exports.setHeavyCacheHeaders = setHeavyCacheHeaders;
exports.serve404 = serve404;
