# 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.itervalues())
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 = file(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(('.hg', '.svn', '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 = file(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.xreadlines())
    new_lines = list(mutator(old_lines, src.name, language))

    for line in src.xreadlines():
        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 = file(dst, 'w')

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