# 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.
#
# Authors: Nathan Binkert

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')
