#! /usr/bin/env python
# -*- python -*-

####################################################################################################
#
# PySpice - A Spice Package for Python
# Copyright (C) 2014 Fabrice Salvaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
####################################################################################################

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

import argparse
import os
import re

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

default_extensions = ','.join(('.py',
))

default_exclusion_pattern = r'(\.git|doc/sphinx/build|dependencies)'

####################################################################################################
#
# Options
#

usage = 'usage: %prog [options]'

parser = argparse.ArgumentParser(description='Replace pattern.')

parser.add_argument('--root-tree-path',
                    default='.',
                    help='root path')

parser.add_argument('--exclude',
                    dest='exclusion_pattern',
                    default=default_exclusion_pattern,
                    help='exclusion regexp [%s]' % (default_exclusion_pattern))

parser.add_argument('--extensions',
                    dest='extensions',
                    default=default_extensions,
                    help='extension [%s]' % (default_extensions))

parser.add_argument('input_pattern', metavar='InputPATTERN',
                    help='input pattern')

parser.add_argument('output_pattern', metavar='OutputPATTERN',
                    help='output pattern')

args = parser.parse_args()

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

def to_absolute_path(path):

    return os.path.abspath(os.path.expanduser(path))

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

def walk(root_tree_path, extensions, exclude_re):

    for root, dirs, files in os.walk(root_tree_path):
        for file_name in files:
            absolut_file_name = os.path.join(root, file_name)
            for extension in extensions:
                if file_name.endswith(extension) and exclude_re.search(absolut_file_name) is None:
                    yield absolut_file_name

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

def process_file(absolut_file_name, input_pattern, output_pattern):

    with open(absolut_file_name) as f:
        content = f.read()
    if input_pattern.search(content):
        print(absolut_file_name)
        backup_absolut_file_name = absolut_file_name + '~'
        os.rename(absolut_file_name, backup_absolut_file_name)
        substituted_content = input_pattern.sub(output_pattern, content)
        with open(absolut_file_name, 'w') as f:
            f.write(substituted_content)

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

program_path = os.path.dirname(os.path.abspath(__file__))
perl_grep = os.path.join(program_path, 'perl-grep')

root_tree_path = to_absolute_path(args.root_tree_path)

extensions = args.extensions.split(',')

# Fixme: never None
if args.exclusion_pattern is not None:
    exclude_re = re.compile(args.exclusion_pattern)
else:
    exclude_re = None

input_pattern_re = re.compile(args.input_pattern)
output_pattern_re = re.compile(args.output_pattern)

for absolut_file_name in walk(root_tree_path, extensions, exclude_re):
    process_file(absolut_file_name, input_pattern_re, args.output_pattern)

####################################################################################################
#
# End
#
####################################################################################################
