//>>excludeStart('excludeAfterBuild', pragmas.excludeAfterBuild)
define(['handlebars', "underscore"], function ( Handlebars, _ ) {

  function replaceLocaleStrings ( ast, mapping, options ) {
    options = options || {};
    mapping = mapping || {};
    // Base set of things
    if ( ast && ast.type === "program" && ast.statements ) {
      _(ast.statements).forEach(function(statement, i){
        var newString = "<!-- i18n error -->";
        // If it's a translation node
        if ( statement.type == "mustache" && statement.id && statement.id.original == "$" ) {

          if ( statement.params.length && statement.params[0].string ) {
            var key = statement.params[0].string;
            newString = mapping[ key ] || (options.originalKeyFallback ? key : newString);
          }
          ast.statements[i] = new Handlebars.AST.ContentNode(newString);
        }
        // If we need to recurse
        else if ( statement.program ) {
          statement.program = replaceLocaleStrings( statement.program, mapping, options );
        }
      });
      // Also cover the else blocks
      if (ast.inverse) {
        replaceLocaleStrings(ast.inverse, mapping, options);
      }
    }
    return ast;
  }

  return function(string, mapping, options) {
    options = options || {};
    var ast, environment;
    ast = Handlebars.parse(string);
    // avoid replacing locale if mapping is `false`
    if (mapping !== false) {
        ast = replaceLocaleStrings(ast, mapping, options);
    }
    environment = new Handlebars.Compiler().compile(ast, options);
    return new Handlebars.JavaScriptCompiler().compile(environment, options);
  };
});
//>>excludeEnd('excludeAfterBuild')
