var Addon      = require('ember-cli/lib/models/addon');
var Funnel     = require('broccoli-funnel');
var mergeTrees = require('broccoli-merge-trees');
var existsSync = require('exists-sync');
var logger     = require('heimdalljs-logger')('template-i18n');
var memoize    = require('lodash.memoize');
var result     = require('lodash.result');
var uniq       = require('lodash.uniq');
var path       = require('path');

/**
 * Collects all addons with a specified name.
 * Walks down the app/addon tree.
 *
 * Returns a list of addon instances with the specified name.
 */
function collectAddons(owner, name) {
  return _collectAddons(owner, name, []);
}

function _collectAddons(owner, name, ret) {
  owner.addons.forEach(function(addon) {
    if (result(addon, 'name') === name) {
      ret.push(addon);
    } else {
      _collectAddons(addon, name, ret);
    }
  });

  return ret;
}

function extractStringsForTranslation(tree, locale) {
  if (tree) {
    return new Funnel(tree, {
      getDestinationPath: function(relativePath) {
        return relativePath.replace(/\.hbs$/, '_' + locale + '.properties');
      }
    });
  }
}

function getAddonPathToParent(addon) {
  var names = [];
  var target = addon;

  while (target) {
    names.unshift(result(target, 'name'));
    target = target.parent;
  }

  return names.join(' -> ');
}

module.exports = Addon.extend({
  isNestedAddon: function() {
    return !!this.parent.parent;
  },

  getParentName: function() {
    return result(this.parent, 'name');
  },

  /**
   * The tree containing extracted + translated .properties files.
   */
  _treeForTranslation: memoize(function treeForTranslation() {
    var trees = [
      extractStringsForTranslation(this._treeForExtraction, 'en_US'),
      this._treeForTranslatedProperties()
    ].filter(Boolean);

    logger.trace(getAddonPathToParent(this));

    return mergeTrees(trees);
  }),

  _treeForTranslatedProperties: memoize(function treeForTranslatedProperties() {
    var i18nPath = path.join(this.parent.root, 'i18n');
    var parentName = this.getParentName();
    var ADDON_TEMPLATES = path.join('addon', 'templates');

    if (existsSync(i18nPath)) {
      logger.info('Found "i18n/" directory in "' + this.parent.root + '"');

      return new Funnel(i18nPath, {
        getDestinationPath: function emberizePath(relativePath) {
          // Move "on-disk" files to their "ember addon" path.
          //
          // From:
          //   addon/templates/components/example-addon-component_en_US.properties
          //
          // To:
          //   modules/<addon-name>/templates/components/example-addon-component_en_US.properties
          //
          if (relativePath.indexOf(ADDON_TEMPLATES) === 0) {
            return path.join(
              'modules',
              parentName,
              relativePath.replace(ADDON_TEMPLATES, 'templates')
            );
          }

          return relativePath;
        }
      });
    } else {
      logger.info('No "i18n/" directory found in "' + this.parent.root + '"');
    }
  }),

  _collectTranslationTrees: memoize(function collectTranslationTrees() {
    var trees = collectAddons(this.parent, result(this, 'name'));

    return trees.map(function(addon) {
      return addon._treeForTranslation();
    });
  })
});

@@ -1514,16 +1514,592 @@
 ;%0A  %7D,%0A%0A
+  /**%0A   * Gets the parent's %22i18n path%22, which is the path where translations can%0A   * be found. The path is relative to the parent's project root.%0A   *%0A   * If no i18n path is configured, the path is assumed to be %22i18n/%22, relative%0A   * to the parent's project root.%0A   *%0A   * @return %7Bstring%7D%0A   */%0A  getParentI18nPath: function() %7B%0A    var parentPkg = this.parent.pkg;%0A    var config = parentPkg%5B'template-i18n'%5D;%0A%0A    if (config && config.i18nPath) %7B%0A      return path.join(this.parent.root, config.i18nPath);%0A    %7D%0A%0A    return path.join(this.parent.root, 'i18n');%0A  %7D,%0A%0A
   /**%0A  

Add getParentI18nPath function