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

var common = require('../common.js');
var utils = common.utils;

exports.setup = function (piccolo) {
  var handle = connect();

  handle.use( connect.compress() );
  handle.use( connect['static'](piccolo.directories['static'], { maxAge: piccolo.settings }) );
  handle.use( connect.staticCache() );

  handle.use( structure(piccolo) );
  handle.use( route(piccolo) );

  connect.errorHandler.title = 'piccolo';
  handle.use (connect.errorHandler() );

  return handle;
};

// handle all /piccolo/ requests
function structure(piccolo) {

  // Read the client core file immediately for performance
  var clientCore = fs.readFileSync(path.join(common.lib, 'core/client.js'));
  var clientCoreLength = clientCore.length;
  var cilentCoreModified = (new Date()).toUTCString();

  return function(req, res, next) {
    // skip if there is no prefix
    if (req.url.indexOf('/piccolo/') !== 0) return next();

    // strip url so the prefix is removed and parse url
    var parsed = url.parse(req.url.substr(8), true);

    // send framework file
    if (parsed.pathname === '/framework.js') {
      res.setHeader('Last-Modified', cilentCoreModified);
      res.setHeader('Content-Length', clientCoreLength);
      res.setHeader('Content-Type', 'application/javascript');
      res.setHeader('Cache-Control', 'public, max-age=' + (piccolo.settings.maxAge / 1000));
      return res.end(clientCore);
    }

    // create httpError error
    return next(utils.httpError(400));
  };
}

function route(piccolo) {

  // Get the route module
  var route = require(piccolo.modules.route);

  return function(req, res) { };
}


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

var common = require('../common.js');
var utils = common.utils;

exports.setup = function (piccolo) {
  var handle = connect();

  handle.use( connect.compress() );
  handle.use( connect['static'](piccolo.directories['static'], { maxAge: piccolo.settings }) );
  handle.use( connect.staticCache() );

  handle.use( structure(piccolo) );
  handle.use( route(piccolo) );

  connect.errorHandler.title = 'piccolo';
  handle.use (connect.errorHandler() );

  return handle;
};

// handle all /piccolo/ requests
function structure(piccolo) {

  var cache = {};
  var startTime = (new Date()).toUTCString();

  // Read the client core file immediately for performance
  function readFile(file) {
    var context = fs.readFileSync(file);
    return {
      'context': context,
      'length': context.length
    };
  }

  // Read core file
  cache.core = readFile(path.join(common.lib, 'core/client.js'));

  // Read modules
  cache.modules = {};
  Object.keys(piccolo.modules).forEach(function (name) {
    cache.modules[name] = readFile(piccolo.modules[name]);
  });

  return function(req, res, next) {
    // Skip if there is no prefix
    if (req.url.indexOf('/piccolo/') !== 0) return next();

    // Strip url so the prefix is removed and parse url
    var parsed = url.parse(req.url.substr(8), true);

    // Set content type to javascript
    res.setHeader('Content-Type', 'application/javascript');
    res.setHeader('Cache-Control', 'public, max-age=' + (piccolo.settings.maxAge / 1000));
    res.setHeader('Last-Modified', startTime);

    // Send static files
    if (parsed.pathname === '/framework.js') {
      res.setHeader('Content-Length', cache.core.length);
      res.end(cache.core.context);
      return;
    }

    // Get file name without .js
    var name = path.basename(parsed.pathname, '.js');

    // translate directory to map property
    var resource;
    if (parsed.pathname.indexOf('/module/') === 0) {
      resource = cache.modules[name];
    }

    // Check that module exist
    if (resource === undefined) {
      return next(utils.httpError(400));
    }

    // Security: do not attempt to understand large callbackID (they are properly not numbers)
    if (parsed.query.id.length > 10) {
      return next(utils.httpError(400));
    }

    // Parse callbackID
    var callbackID = parseInt(parsed.query.id, 10);

    // Could not parse (NaN check)
    if (callbackID !== callbackID) {
      return next(utils.httpError(400));
    }

    // create prefix and postfix
    var prefix = ';(function() {\n  var exports = {}; \n';
    var postfix = '\n  window.piccolo.loaded(' + callbackID + ', exports);\n})();';

    // Calculate content length
    res.setHeader('Content-Length', prefix.length + resource.length + postfix.length);

    // Send module context
    res.write(prefix);
    res.write(cache.modules[name].context);
    res.end(postfix);
  };
}

function route(piccolo) {

  // Get the route module
  var route = require(piccolo.modules.route);

  return function(req, res) { };
}

add piccolo module interface for client side