# Copyright (c) 2010 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os

# lanuage type for each file extension
lang_types = {
    '.c'     : "C",
    '.cl'    : "C",
    '.h'     : "C",
    '.cc'    : "C++",
    '.hh'    : "C++",
    '.cxx'   : "C++",
    '.hxx'   : "C++",
    '.cpp'   : "C++",
    '.hpp'   : "C++",
    '.C'     : "C++",
    '.H'     : "C++",
    '.i'     : "swig",
    '.py'    : "python",
    '.pl'    : "perl",
    '.pm'    : "perl",
    '.s'     : "asm",
    '.S'     : "asm",
    '.l'     : "lex",
    '.ll'    : "lex",
    '.y'     : "yacc",
    '.yy'    : "yacc",
    '.isa'   : "isa",
    '.sh'    : "shell",
    '.slicc' : "slicc",
    '.sm'    : "slicc",
    '.awk'   : "awk",
    '.el'    : "lisp",
    '.txt'   : "text",
    '.tex'   : "tex",
    '.mk'    : "make",
    '.dts'    : "dts",
    }

# languages based on file prefix
lang_prefixes = (
    ('SCons',    'scons'),
    ('Make',     'make'),
    ('make',     'make'),
    ('Doxyfile', 'doxygen'),
    )

# languages based on #! line of first file
hash_bang = (
    ('python', 'python'),
    ('perl',   'perl'),
    ('sh',     'shell'),
    )

# the list of all languages that we detect
all_languages = frozenset(lang_types.values())
all_languages |= frozenset(lang for start,lang in lang_prefixes)
all_languages |= frozenset(lang for start,lang in hash_bang)

def lang_type(filename, firstline=None, openok=True):
    '''identify the language of a given filename and potentially the
    firstline of the file.  If the firstline of the file is not
    provided and openok is True, open the file and read the first line
    if necessary'''

    basename = os.path.basename(filename)
    name,extension = os.path.splitext(basename)

    # first try to detect language based on file extension
    try:
        return lang_types[extension]
    except KeyError:
        pass

    # now try to detect language based on file prefix
    for start,lang in lang_prefixes:
        if basename.startswith(start):
            return lang

    # if a first line was not provided but the file is ok to open,
    # grab the first line of the file.
    if firstline is None and openok:
        handle = open(filename, 'r')
        firstline = handle.readline()
        handle.close()

    # try to detect language based on #! in first line
    if firstline and firstline.startswith('#!'):
        for string,lang in hash_bang:
            if firstline.find(string) > 0:
                return lang

    # sorry, we couldn't detect the language
    return None

# directories and files to ignore by default
default_dir_ignore = frozenset(('build', 'ext'))
default_file_ignore = frozenset(('parsetab.py', ))

def find_files(base, languages=all_languages,
               dir_ignore=default_dir_ignore,
               file_ignore=default_file_ignore):
    '''find all files in a directory and its subdirectories based on a
    set of languages, ignore directories specified in dir_ignore and
    files specified in file_ignore'''
    if base[-1] != '/':
        base += '/'

    def update_dirs(dirs):
        '''strip the ignored directories out of the provided list'''
        index = len(dirs) - 1
        for i,d in enumerate(reversed(dirs)):
            if d in dir_ignore:
                del dirs[index - i]

    # walk over base
    for root,dirs,files in os.walk(base):
        root = root.replace(base, '', 1)

        # strip ignored directories from the list
        update_dirs(dirs)

        for filename in files:
            if filename in file_ignore:
                # skip ignored files
                continue

            # try to figure out the language of the specified file
            fullpath = os.path.join(base, root, filename)
            language = lang_type(fullpath)

            # if the file is one of the langauges that we want return
            # its name and the language
            if language in languages:
                yield fullpath, language

def update_file(dst, src, language, mutator):
    '''update a file of the specified language with the provided
    mutator generator.  If inplace is provided, update the file in
    place and return the handle to the updated file.  If inplace is
    false, write the updated file to cStringIO'''

    # if the source and destination are the same, we're updating in place
    inplace = dst == src

    if isinstance(src, str):
        # if a filename was provided, open the file
        if inplace:
            mode = 'r+'
        else:
            mode = 'r'
        src = open(src, mode)

    orig_lines = []

    # grab all of the lines of the file and strip them of their line ending
    old_lines = list(line.rstrip('\r\n') for line in src)
    new_lines = list(mutator(old_lines, src.name, language))

    for line in src:
        line = line

    if inplace:
        # if we're updating in place and the file hasn't changed, do nothing
        if old_lines == new_lines:
            return

        # otherwise, truncate the file and seek to the beginning.
        dst = src
        dst.truncate(0)
        dst.seek(0)
    elif isinstance(dst, str):
        # if we're not updating in place and a destination file name
        # was provided, create a file object
        dst = open(dst, 'w')

    for line in new_lines:
        dst.write(line)
        dst.write('\n')
