#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Module that sanitizes source files with specified modifiers."""


import commands
import os
import sys


_FILE_EXTENSIONS_TO_SANITIZE = ['cpp', 'h', 'c', 'gyp', 'gypi']

_SUBDIRS_TO_IGNORE = ['.svn', 'third_party']


def SanitizeFilesWithModifiers(directory, file_modifiers, line_modifiers):
  """Sanitizes source files with the specified file and line modifiers.

  Args:
    directory: string - The directory which will be recursively traversed to
        find source files to apply modifiers to.
    file_modifiers: list - file-modification methods which should be applied to
        the complete file content (Eg: EOFOneAndOnlyOneNewlineAdder).
    line_modifiers: list - line-modification methods which should be applied to
        lines in a file (Eg: TabReplacer).
  """
  for item in os.listdir(directory):

    full_item_path = os.path.join(directory, item)

    if os.path.isfile(full_item_path):  # Item is a file.

      # Only sanitize files with extensions we care about.
      if (len(full_item_path.split('.')) > 1 and
          full_item_path.split('.')[-1] in _FILE_EXTENSIONS_TO_SANITIZE):
        f = file(full_item_path)
        try:
          lines = f.readlines()
        finally:
          f.close()

        new_lines = []  # Collect changed lines here.
        line_number = 0  # Keeps track of line numbers in the source file.
        write_to_file = False  # File is written to only if this flag is set.

        # Run the line modifiers for each line in this file.
        for line in lines:
          original_line = line
          line_number += 1

          for modifier in line_modifiers:
            line = modifier(line, full_item_path, line_number)
            if original_line != line:
              write_to_file = True
          new_lines.append(line)

        # Run the file modifiers.
        old_content = ''.join(lines)
        new_content = ''.join(new_lines)
        for modifier in file_modifiers:
          new_content = modifier(new_content, full_item_path)
        if new_content != old_content:
          write_to_file = True

        # Write modifications to the file.
        if write_to_file:
          f = file(full_item_path, 'w')
          try:
            f.write(new_content)
          finally:
            f.close()
          print 'Made changes to %s' % full_item_path

    elif item not in _SUBDIRS_TO_IGNORE:
      # Item is a directory recursively call the method.
      SanitizeFilesWithModifiers(full_item_path, file_modifiers, line_modifiers)


############## Line Modification methods ##############


def TrailingWhitespaceRemover(line, file_path, line_number):
  """Strips out trailing whitespaces from the specified line."""
  stripped_line = line.rstrip() + '\n'
  if line != stripped_line:
    print 'Removing trailing whitespace in %s:%s' % (file_path, line_number)
  return stripped_line


def CrlfReplacer(line, file_path, line_number):
  """Replaces CRLF with LF."""
  if '\r\n' in line:
    print 'Replacing CRLF with LF in %s:%s' % (file_path, line_number)
  return line.replace('\r\n', '\n')


def TabReplacer(line, file_path, line_number):
  """Replaces Tabs with 4 whitespaces."""
  if '\t' in line:
    print 'Replacing Tab with whitespace in %s:%s' % (file_path, line_number)
  return line.replace('\t', '    ')


############## File Modification methods ##############


def CopywriteChecker(file_content, unused_file_path):
  """Ensures that the copywrite information is correct."""
  # TODO(rmistry): Figure out the legal implications of changing old copyright
  # headers.
  return file_content


def EOFOneAndOnlyOneNewlineAdder(file_content, file_path):
  """Adds one and only one LF at the end of the file."""
  if file_content and (file_content[-1] != '\n' or file_content[-2:-1] == '\n'):
    file_content = file_content.rstrip()
    file_content += '\n'
    print 'Added exactly one newline to %s' % file_path
  return file_content


def SvnEOLChecker(file_content, file_path):
  """Sets svn:eol-style property to LF."""
  output = commands.getoutput(
      'svn propget svn:eol-style %s' % file_path)
  if output != 'LF':
    print 'Setting svn:eol-style property to LF in %s' % file_path
    os.system('svn ps svn:eol-style LF %s' % file_path)
  return file_content


#######################################################


if '__main__' == __name__:
  sys.exit(SanitizeFilesWithModifiers(
      os.getcwd(),
      file_modifiers=[
          CopywriteChecker,
          EOFOneAndOnlyOneNewlineAdder,
          SvnEOLChecker,
      ],
      line_modifiers=[
          CrlfReplacer,
          TabReplacer,
          TrailingWhitespaceRemover,
      ],
  ))
