(function() {
  var asar, asarStatsToFsStats, error, fakeTime, fs, gid, module_findPath, nextInode, node_module, path, readFileSync, realpathSync, splitPath, statSync, uid;

  asar = require('asar');

  fs = require('fs');

  path = require('path');

  try {
    node_module = require('module');
  } catch (_error) {
    error = _error;
    node_module = null;
  }

  splitPath = function(p) {
    var index;
    if (typeof p !== 'string') {
      return [false];
    }
    if (p.substr(-5) === '.asar') {
      return [true, p, ''];
    }
    index = p.lastIndexOf(".asar" + path.sep);
    if (index === -1) {
      return [false];
    }
    return [true, p.substr(0, index + 5), p.substr(index + 6)];
  };

  nextInode = 0;

  uid = process.getuid != null ? process.getuid() : 0;

  gid = process.getgid != null ? process.getgid() : 0;

  fakeTime = new Date();

  asarStatsToFsStats = function(stats) {
    var isFile;
    isFile = !stats.files;
    return {
      dev: 1,
      ino: ++nextInode,
      mode: 33188,
      nlink: 1,
      uid: uid,
      gid: gid,
      rdev: 0,
      atime: stats.atime || fakeTime,
      birthtime: stats.birthtime || fakeTime,
      mtime: stats.mtime || fakeTime,
      ctime: stats.ctime || fakeTime,
      size: stats.size,
      isFile: function() {
        return isFile;
      },
      isDirectory: function() {
        return !isFile;
      },
      isSymbolicLink: function() {
        return false;
      },
      isBlockDevice: function() {
        return false;
      },
      isCharacterDevice: function() {
        return false;
      },
      isFIFO: function() {
        return false;
      },
      isSocket: function() {
        return false;
      }
    };
  };

  readFileSync = fs.readFileSync;

  fs.readFileSync = function(p, options) {
    var asarPath, content, filePath, isAsar, _ref;
    _ref = splitPath(p), isAsar = _ref[0], asarPath = _ref[1], filePath = _ref[2];
    if (!isAsar) {
      return readFileSync.apply(this, arguments);
    }
    if (!options) {
      options = {
        encoding: null,
        flag: 'r'
      };
    } else if (typeof options === 'string') {
      options = {
        encoding: options,
        flag: 'r'
      };
    } else if (typeof options !== 'object') {
      throw new TypeError('Bad arguments');
    }
    content = asar.extractFile(asarPath, filePath);
    if (options.encoding) {
      return content.toString(options.encoding);
    } else {
      return content;
    }
  };

  statSync = fs.statSync;

  fs.statSync = function(p) {
    var asarPath, filePath, isAsar, _ref;
    _ref = splitPath(p), isAsar = _ref[0], asarPath = _ref[1], filePath = _ref[2];
    if (!isAsar) {
      return statSync.apply(this, arguments);
    }
    return asarStatsToFsStats(asar.statFile(asarPath, filePath));
  };

  realpathSync = fs.realpathSync;

  fs.realpathSync = function(p) {
    var asarPath, filePath, isAsar, stat, _ref;
    _ref = splitPath(p), isAsar = _ref[0], asarPath = _ref[1], filePath = _ref[2];
    if (!isAsar) {
      return realpathSync.apply(this, arguments);
    }
    stat = asar.statFile(asarPath, filePath);
    if (stat.link) {
      filePath = stat.link;
    }
    return path.join(realpathSync(asarPath), filePath);
  };

  if (node_module && node_module._findPath) {
    module_findPath = node_module._findPath;
    node_module._findPath = function(request, paths, isMain) {
      var asarPath, filePath, isAsar, _ref;
      _ref = splitPath(request), isAsar = _ref[0], asarPath = _ref[1], filePath = _ref[2];
      if (!isAsar) {
        return module_findPath.apply(this, arguments);
      }
      return request;
    };
  }

}).call(this);
