text: const _ = require('underscore');
  const GitCommander = require('./gitCommander');
  
  /**
   * @module Grapher
   *
   * Grapher is a Class that should be instantiated with an atom 'Git' object
   * for the root repository in the project.
   *
   * @param {Git} repo - an instance of 'Git' class from atom workspace. See
   *   https://atom.io/docs/api/v0.92.0/api/ for more info.
   */
  var Grapher = function(repo) {
    if (!repo) {
      throw new Error('Cannot create a Grapher without a repository.');
    }
  
    this.repo = repo;
    this.initialize();
  };
  
  // ================
  // Instance Methods
  // ================
  
  _.extend(Grapher.prototype, {
  
    /**
     * Initializes this Grapher instance, by creating git-tools repos for the root
     * repository and submodules.
     */
    initialize: function() {
      this.tools = {};
      this.tools.root = new GitCommander(this.repo.getWorkingDirectory());
  
      var submodules = this.repo.submodules;
      if (submodules) {
        for (var submodulePath in submodules) {
          this.tools[submodulePath] = new GitCommander(this.repo.getWorkingDirectory() + '/' + submodulePath);
        }
      }
    },
  
    /**
     * Graphs the given filePath and calls callback with graph lines or error.
     *
     * @param {string} filePath - filePath to graph
     * @param {function} callback - callback to call back with graph data
     */
    graph: function(filePath, callback) {
      // Ensure file path is relative to root repo
      filePath = this.repo.relativize(filePath);
      var repoUtil = this.repoUtilForPath(filePath);
  
      // Ensure that if this file is in a submodule, we remove the submodule dir
      // from the path
      filePath = this.removeSubmodulePrefix(filePath);
  
      if (!_.isFunction(callback)) {
        throw new Error('Must be called with a callback function');
      }
  
      // Make the async graph call on the git repo
      repoUtil.graph(filePath, function(err, graph) {
        callback(err, graph);
      });
    },
  
    /**
     * Utility to get the GitCommander repository for the given filePath. Takes into
     * account whether the file is part of a submodule and returns that repository
     * if necessary.
     *
     * @param {string} filePath - the path to the file in question.
     */
    repoUtilForPath: function(filePath) {
      var submodules = this.repo.submodules;
  
      // By default, we return the root GitCommander repository.
      var repoUtil = this.tools.root;
  
      // if we have submodules, loop through them and see if the given file path
      // belongs inside one of the repositories. If so, we return the GitCommander repo
      // for that submodule.
      if (submodules) {
        for (var submodulePath in submodules) {
          var submoduleRegex = new RegExp('^' + submodulePath);
          if (submoduleRegex.test(filePath)) {
            repoUtil = this.tools[submodulePath];
          }
        }
      }
  
      return repoUtil;
    },
  
    /**
     * If the file path given is inside a submodule, removes the submodule
     * directory prefix.
     *
     * @param {string} filePath - path to file to relativize
     * @param {Repo} toolsRepo - git-tools Repo
     */
    removeSubmodulePrefix: function(filePath) {
      var submodules = this.repo.submodules;
      if (submodules) {
        for (var submodulePath in submodules) {
          var submoduleRegex = new RegExp('^' + submodulePath);
          if (submoduleRegex.test(filePath)) {
            filePath = filePath.replace(submoduleRegex, '');
          }
        }
      }
  
      // remove leading '/' if there is one before returning
      filePath = filePath.replace(/^\//, '');
      return filePath;
    }
  
  });
  
  // ================
  // Exports
  // ================
  
  module.exports = Grapher;
  