(function() {
  var ChunkedExecutor, ChunkedLineReader, EOL, EventEmitter, PathReplacer, ReplaceTransformer, Transform, fs, temp,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  fs = require('fs');

  temp = require('temp').track();

  EventEmitter = require('events').EventEmitter;

  Transform = require('stream').Transform;

  EOL = require('os').EOL;

  ChunkedExecutor = require('./chunked-executor');

  ChunkedLineReader = require('./chunked-line-reader');

  ReplaceTransformer = (function(superClass) {
    extend(ReplaceTransformer, superClass);

    function ReplaceTransformer(regex1, replacementText1, arg) {
      this.regex = regex1;
      this.replacementText = replacementText1;
      this.dryReplace = arg.dryReplace;
      this.replacements = 0;
      ReplaceTransformer.__super__.constructor.call(this);
    }

    ReplaceTransformer.prototype._transform = function(chunk, encoding, done) {
      var data, matches;
      data = chunk.toString();
      matches = data.match(this.regex);
      if (matches) {
        this.replacements += matches.length;
      }
      if (matches && !this.dryReplace) {
        data = data.replace(this.regex, this.replacementText);
      }
      this.push(data, 'utf8');
      return done();
    };

    return ReplaceTransformer;

  })(Transform);

  module.exports = PathReplacer = (function(superClass) {
    extend(PathReplacer, superClass);

    function PathReplacer(arg) {
      this.dryReplace = (arg != null ? arg : {}).dryReplace;
    }

    PathReplacer.prototype.replacePaths = function(regex, replacementText, paths, doneCallback) {
      var errors, replacePath, results;
      errors = null;
      results = null;
      replacePath = (function(_this) {
        return function(filePath, pathCallback) {
          return _this.replacePath(regex, replacementText, filePath, function(result, error) {
            if (result) {
              if (results == null) {
                results = [];
              }
              results.push(result);
            }
            if (error) {
              if (errors == null) {
                errors = [];
              }
              errors.push(error);
            }
            return pathCallback();
          });
        };
      })(this);
      return new ChunkedExecutor(paths, replacePath).execute(function() {
        return doneCallback(results, errors);
      });
    };

    PathReplacer.prototype.replacePath = function(regex, replacementText, filePath, doneCallback) {
      var error, output, reader, replacer;
      reader = new ChunkedLineReader(filePath);
      try {
        if (reader.isBinaryFile()) {
          return doneCallback(null);
        }
      } catch (_error) {
        error = _error;
        this.emit('file-error', error);
        return doneCallback(null, error);
      }
      replacer = new ReplaceTransformer(regex, replacementText, {
        dryReplace: this.dryReplace
      });
      output = temp.createWriteStream();
      output.on('finish', (function(_this) {
        return function() {
          var readStream, replacements, result, writeStream;
          result = null;
          if (replacements = replacer.replacements) {
            result = {
              filePath: filePath,
              replacements: replacements
            };
            _this.emit('path-replaced', result);
          }
          readStream = fs.createReadStream(output.path);
          writeStream = fs.createWriteStream(filePath);
          writeStream.on('finish', function() {
            return doneCallback(result);
          });
          try {
            return readStream.pipe(writeStream);
          } catch (_error) {
            error = _error;
            _this.emit('file-error', error);
            return doneCallback(null, error);
          }
        };
      })(this));
      reader.on('error', (function(_this) {
        return function(error) {
          _this.emit('file-error', error);
          return doneCallback(null, error);
        };
      })(this));
      return reader.pipe(replacer).pipe(output);
    };

    return PathReplacer;

  })(EventEmitter);

}).call(this);
