#!/usr/bin/env python

import os

def _usage( ):
   result = [ ]
   result.append('')
   result.append('Usage:')
   result.append('')
   result.append('replace-in-files DIR OLD_TEXT NEW_TEXT [CONFIRM=true/false]')
   result.append('')
   result.append('Crawl directory DIR and read every file in it recursively. ')
   result.append('Replace OLD_TEXT with NEW_TEXT in each file.')
   result.append('')
   result.append('Set CONFIRM to `false` to replace without prompting.')
   result.append('')
   result = '\n'.join(['\t' + line for line in result])
   return result

def _remove_dirs(skip_dirs, dirs):
   for dir in skip_dirs:
      if dir in dirs:
         dirs.remove(dir)

def _remove_files(skip_files, files):
   for x in skip_files: 
      #for file in files:   
      for file in files[:]:   
         if file.endswith(x):
            files.remove(file)

def replace_in_files(dir, old, new, skip_dirs=['.svn'], confirm=True):
   skip_files = ['replace-in-files', '.pyc', '.rst']

   for root, dirs, files in os.walk(dir):
      _remove_dirs(skip_dirs, dirs)
      _remove_files(skip_files, files)
      ## replace old with new
      for file in files:
         file = os.path.join(root, file)
         pf = open(file, 'r')
         print "Working on file: %s" % file
         new_text = [ ]
         old_text = pf.readlines( )
         for line in old_text:
            if old in line:
               if confirm:
                  print line,
                  replace = raw_input('Replace [y/n]? ')
                  if replace.lower( ) == 'y':
                     line = line.replace(old, new)
               else:
                  line = line.replace(old, new)
            new_text.append(line)

         pf.close( )
         new_file = open(file, 'w')
         new_file.writelines(new_text)


if __name__ == '__main__':
   import sys
   if len(sys.argv) < 4:
      print _usage( )
      sys.exit(2)

   dir = sys.argv[1]
   old = sys.argv[2]
   new = sys.argv[3]
   skip_dirs = ['.svn']
   confirm = True
   if len(sys.argv) == 5 and sys.argv[4].lower( ) == 'false':
      confirm = False

   replace_in_files(dir, old, new, skip_dirs, confirm)
