var path = require('path'); // if module is locally defined we path.resolve it
var callsite = require('callsite');

require.find = function (moduleName) {
  if (moduleName[0] === '.') {
    var stack = callsite();
    for (var i in stack) {
      var filename = stack[i].getFileName();
      if (filename !== module.filename) {
        moduleName = path.resolve(path.dirname(filename), moduleName);
        break;
      }
    }
  }
  try {
    return require.resolve(moduleName);
  } catch (e) {
    return;
  }
};

/**
 * Removes a module from the cache. We need this to re-load our http_request !
 * see: http://stackoverflow.com/a/14801711/1148249
 */
require.decache = function (moduleName) {

    moduleName = require.find(moduleName);

    if(!moduleName) {return;}

    // Run over the cache looking for the files
    // loaded by the specified module name
    require.searchCache(moduleName, function (mod) {
        delete require.cache[mod.id];
    });

    // Remove cached paths to the module.
    // Thanks to @bentael for pointing this out.
    Object.keys(module.constructor._pathCache).forEach(function(cacheKey) {
        if (cacheKey.indexOf(moduleName)>0) {
            delete module.constructor._pathCache[cacheKey];
        }
    });
};

/**
 * Runs over the cache to search for all the cached
 * files
 */
require.searchCache = function (moduleName, callback) {
    // Resolve the module identified by the specified name
    var mod = require.resolve(moduleName);
    var visited = {};

    // Check if the module has been resolved and found within
    // the cache no else so #ignore else http://git.io/vtgMI
    /* istanbul ignore else */
    if (mod && ((mod = require.cache[mod]) !== undefined)) {
        // Recursively go over the results
        (function run(current) {
            visited[current.id] = true;
            // Go over each of the module's children and
            // run over it
            current.children.forEach(function (child) {
                // ignore .node files, decachine native modules throws a
                // "module did not self-register" error on second require
                if (path.extname(child.filename) !== '.node' && !visited[child.id]) {
                    run(child);
                }
            });

            // Call the specified callback providing the
            // found module
            callback(current);
        })(mod);
    }
};

module.exports = require.decache;