#!/usr/bin/env python2
#
# Copyright (c) 2014-2015 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2011 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
#          Andreas Sandberg

import os
import re
import sys

from file_types import *

cpp_c_headers = {
    'assert.h' : 'cassert',
    'ctype.h'  : 'cctype',
    'errno.h'  : 'cerrno',
    'float.h'  : 'cfloat',
    'limits.h' : 'climits',
    'locale.h' : 'clocale',
    'math.h'   : 'cmath',
    'setjmp.h' : 'csetjmp',
    'signal.h' : 'csignal',
    'stdarg.h' : 'cstdarg',
    'stddef.h' : 'cstddef',
    'stdio.h'  : 'cstdio',
    'stdlib.h' : 'cstdlib',
    'string.h' : 'cstring',
    'time.h'   : 'ctime',
    'wchar.h'  : 'cwchar',
    'wctype.h' : 'cwctype',
}

include_re = re.compile(r'([#%])(include|import).*[<"](.*)[">]')
def include_key(line):
    '''Mark directories with a leading space so directories
    are sorted before files'''

    match = include_re.match(line)
    assert match, line
    keyword = match.group(2)
    include = match.group(3)

    # Everything but the file part needs to have a space prepended
    parts = include.split('/')
    if len(parts) == 2 and parts[0] == 'dnet':
        # Don't sort the dnet includes with respect to each other, but
        # make them sorted with respect to non dnet includes.  Python
        # guarantees that sorting is stable, so just clear the
        # basename part of the filename.
        parts[1] = ' '
    parts[0:-1] = [ ' ' + s for s in parts[0:-1] ]
    key = '/'.join(parts)

    return key


def _include_matcher(keyword="#include", delim="<>"):
    """Match an include statement and return a (keyword, file, extra)
    duple, or a touple of None values if there isn't a match."""

    rex = re.compile(r'^(%s)\s*%s(.*)%s(.*)$' % (keyword, delim[0], delim[1]))

    def matcher(context, line):
        m = rex.match(line)
        return m.groups() if m else (None, ) * 3

    return matcher

def _include_matcher_fname(fname, **kwargs):
    """Match an include of a specific file name. Any keyword arguments
    are forwarded to _include_matcher, which is used to match the
    actual include line."""

    rex = re.compile(fname)
    base_matcher = _include_matcher(**kwargs)

    def matcher(context, line):
        (keyword, fname, extra) = base_matcher(context, line)
        if fname and rex.match(fname):
            return (keyword, fname, extra)
        else:
            return (None, ) * 3

    return matcher


def _include_matcher_main():
    """Match a C/C++ source file's primary header (i.e., a file with
    the same base name, but a header extension)."""

    base_matcher = _include_matcher(delim='""')
    rex = re.compile(r"^src/(.*)\.([^.]+)$")
    header_map = {
        "c" : "h",
        "cc" : "hh",
        "cpp" : "hh",
        }
    def matcher(context, line):
        m = rex.match(context["filename"])
        if not m:
            return (None, ) * 3
        base, ext = m.groups()
        (keyword, fname, extra) = base_matcher(context, line)
        try:
            if fname == "%s.%s" % (base, header_map[ext]):
                return (keyword, fname, extra)
        except KeyError:
            pass

        return (None, ) * 3

    return matcher

class SortIncludes(object):
    # different types of includes for different sorting of headers
    # <Python.h>         - Python header needs to be first if it exists
    # <*.h>              - system headers (directories before files)
    # <*>                - STL headers
    # <*.(hh|hxx|hpp|H)> - C++ Headers (directories before files)
    # "*"                - M5 headers (directories before files)
    includes_re = (
        ('main', '""', _include_matcher_main()),
        ('python', '<>', _include_matcher_fname("^Python\.h$")),
        ('pybind', '""', _include_matcher_fname("^pybind11/.*\.h$",
                                                delim='""')),
        ('c', '<>', _include_matcher_fname("^.*\.h$")),
        ('stl', '<>', _include_matcher_fname("^\w+$")),
        ('cc', '<>', _include_matcher_fname("^.*\.(hh|hxx|hpp|H)$")),
        ('m5header', '""', _include_matcher_fname("^.*\.h{1,2}$", delim='""')),
        ('swig0', '<>', _include_matcher(keyword="%import")),
        ('swig1', '<>', _include_matcher(keyword="%include")),
        ('swig2', '""', _include_matcher(keyword="%import", delim='""')),
        ('swig3', '""', _include_matcher(keyword="%include", delim='""')),
        )

    block_order = (
        ('python', ),
        ('pybind', ),
        ('main', ),
        ('c', ),
        ('stl', ),
        ('cc', ),
        ('m5header', ),
        ('swig0', 'swig1', 'swig2', 'swig3', ),
        )

    def __init__(self):
        self.block_priority = {}
        for prio, keys in enumerate(self.block_order):
            for key in keys:
                self.block_priority[key] = prio

    def reset(self):
        # clear all stored headers
        self.includes = {}

    def dump_blocks(self, block_types):
        """Merge includes of from several block types into one large
        block of sorted includes. This is useful when we have multiple
        include block types (e.g., swig includes) with the same
        priority."""

        includes = []
        for block_type in block_types:
            try:
                includes += self.includes[block_type]
            except KeyError:
                pass

        return sorted(set(includes))

    def dump_includes(self):
        includes = []
        for types in self.block_order:
            block = self.dump_blocks(types)
            if includes and block:
                includes.append("")
            includes += block

        self.reset()
        return includes

    def __call__(self, lines, filename, language):
        self.reset()

        context = {
            "filename" : filename,
            "language" : language,
            }

        def match_line(line):
            if not line:
                return (None, line)

            for include_type, (ldelim, rdelim), matcher in self.includes_re:
                keyword, include, extra = matcher(context, line)
                if keyword:
                    # if we've got a match, clean up the #include line,
                    # fix up stl headers and store it in the proper category
                    if include_type == 'c' and language == 'C++':
                        stl_inc = cpp_c_headers.get(include, None)
                        if stl_inc:
                            include = stl_inc
                            include_type = 'stl'

                    return (include_type,
                            keyword + ' ' + ldelim + include + rdelim + extra)

            return (None, line)

        processing_includes = False
        for line in lines:
            include_type, line = match_line(line)
            if include_type:
                try:
                    self.includes[include_type].append(line)
                except KeyError:
                    self.includes[include_type] = [ line ]

                processing_includes = True
            elif processing_includes and not line.strip():
                # Skip empty lines while processing includes
                pass
            elif processing_includes:
                # We are now exiting an include block
                processing_includes = False

                # Output pending includes, a new line between, and the
                # current l.
                for include in self.dump_includes():
                    yield include
                yield ''
                yield line
            else:
                # We are not in an include block, so just emit the line
                yield line

        # We've reached EOF, so dump any pending includes
        if processing_includes:
            for include in self.dump_includes():
                yield include

# default language types to try to apply our sorting rules to
default_languages = frozenset(('C', 'C++', 'isa', 'python', 'scons', 'swig'))

def options():
    import optparse
    options = optparse.OptionParser()
    add_option = options.add_option
    add_option('-d', '--dir_ignore', metavar="DIR[,DIR]", type='string',
               default=','.join(default_dir_ignore),
               help="ignore directories")
    add_option('-f', '--file_ignore', metavar="FILE[,FILE]", type='string',
               default=','.join(default_file_ignore),
               help="ignore files")
    add_option('-l', '--languages', metavar="LANG[,LANG]", type='string',
               default=','.join(default_languages),
               help="languages")
    add_option('-n', '--dry-run', action='store_true',
               help="don't overwrite files")

    return options

def parse_args(parser):
    opts,args = parser.parse_args()

    opts.dir_ignore = frozenset(opts.dir_ignore.split(','))
    opts.file_ignore = frozenset(opts.file_ignore.split(','))
    opts.languages = frozenset(opts.languages.split(','))

    return opts,args

if __name__ == '__main__':
    parser = options()
    opts, args = parse_args(parser)

    for base in args:
        for filename,language in find_files(base, languages=opts.languages,
                file_ignore=opts.file_ignore, dir_ignore=opts.dir_ignore):
            if opts.dry_run:
                print "%s: %s" % (filename, language)
            else:
                update_file(filename, filename, language, SortIncludes())
