var juice = require('../juice');

var Context = exports.Context = function Context(app, request) {

  function AppContext(request) {
    this.stash = {};
    this.request = request;
  }
  AppContext.prototype = app;

  var ctx = new AppContext(request);

  // Now copy things from the Context.prototype to ctx object -- poor mans MI
  for (var i in Context.prototype) {
    if (Context.prototype.hasOwnProperty(i))
      ctx[i] = Context.prototype[i];
  }

  var j_env = { docRoot: this.docRoot };
  if ("env" in request == false)
    request.env = { juice: j_env };
  else
    request.env.juice = j_env;

  ctx.base = request.scheme + "://"
           + ctx.request.host + ":"
           + ctx.request.port
           + ctx.request.scriptName + "/";

  // Pull params into objects
  ctx.buildParams();

  return ctx;

}

Context.prototype.runAction = function runAction(captures, action) {

  var data = action.action.apply(this, captures);
  var res, redirect;

  if (action.raw) {
    return data;
  }
  if (this.format == "json") {
    res = {
      status: 200,
      headers: { contentType : 'application/json' },
      body: [ data.toSource() ]
    };
  }
  else if ( ( redirect = this.redirectTo || action.redirect ) ) {
    var headers = new (juice.Utils.Headers);
    headers.location = this.urlFor(redirect);
    res = {
      status:302,
      headers: headers,
      body: []
    };
  }
  else if (action.render) {
    data.juice = this.helpers;
    data.juice.urlFor = this.urlFor.bind(this);

    const fs = require('filesystem-base');

    var templates = JSON.parse( fs.rawOpen( this.docRoot + 'conf/templates.json' ).readWhole() );

    for ( let ext in templates ) {
      let path = this.docRoot + 'templates/' + action.render + '.' + ext;
      if ( fs.isFile( path ) ) {
        var t = fs.rawOpen( path, 'r' ).readWhole();
        var body = require( templates[ ext ] ).render( data, t )
        break;
      }
    }

    if ( body === undefined )
      throw "Couldn't find template file to load";

    res = {
      status: 200,
      headers: { contentType : 'text/html' },
      body: [ body ]
    };
  }
  else {
    throw new Error( "You need to specify a redirect or a template to render" );
  }

  return res;
}

Context.prototype.urlFor = function() {
  var url = Array.join(arguments, '/');
  url = url.replace(/\/+/g, '/')
           .replace(/^\//, '');

  return this.base + url;
}

Context.prototype.buildParams = function buildParams() {
  var store = this.request.env.juice;
  store.params = {
    get: this.request.queryString ? juice.Utils.splitQueryString(this.request.queryString) : {},
    post: {}
  };

  var len = this.request.headers['content-length'];
  if (len && this.request.method == "POST" &&
      this.request.headers['content-type'] == 'application/x-www-form-urlencoded')
  {
    var body = this.request.input.read(len).decodeToString();
    store.params.post = juice.Utils.splitQueryString(body);
  }

  this.params = store.params;
}


@@ -1505,441 +1505,8 @@
 );%0A%0A
-    const fs = require('filesystem-base');%0A%0A    var templates = JSON.parse( fs.rawOpen( this.docRoot + 'conf/templates.json' ).readWhole() );%0A%0A    for ( let ext in templates ) %7B%0A      let path = this.docRoot + 'templates/' + action.render + '.' + ext;%0A      if ( fs.isFile( path ) ) %7B%0A        var t = fs.rawOpen( path, 'r' ).readWhole();%0A        var body = require( templates%5B ext %5D ).render( data, t )%0A        break;%0A      %7D%0A    %7D%0A%0A
     
@@ -2550,12 +2550,699 @@
 .params;%0A%7D%0A%0A
+Context.prototype.renderTemplate = function( file, stash ) %7B%0A  // load templates config or default to TT if not available%0A  var conf = this.config( 'templates' ) %7C%7C %7B %22tt%22 : %22Template%22 %7D;%0A%0A  const fs = require('filesystem-base');%0A%0A  for ( let ext in conf ) %7B%0A    // build the path to the template using the extension from conf%0A    var path = this.docRoot + 'templates/' + file + '.' + ext;%0A%0A    // if the template exists, render it with the right engine and return%0A    if ( fs.isFile( path ) ) %7B%0A      let template = fs.rawOpen( path, 'r' ).readWhole();%0A      let engine = require( conf%5B ext %5D );%0A      return engine.render( stash, template );%0A    %7D%0A  %7D%0A%0A  throw %22Template not found%22;%0A%7D%0A

Refactor template rendering to its own method