#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright (c) 2012, Cloudscaling
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""tempest HACKING file compliance testing

built on top of pep8.py
"""

import inspect
import logging
import os
import re
import subprocess
import sys
import tokenize
import warnings

import pep8

# Don't need this for testing
logging.disable('LOG')

#T1xx comments
#T2xx except
#T3xx imports
#T4xx docstrings
#T5xx dictionaries/lists
#T6xx calling methods
#T7xx localization
#N8xx git commit messages

IMPORT_EXCEPTIONS = ['sqlalchemy', 'migrate']
DOCSTRING_TRIPLE = ['"""', "'''"]
VERBOSE_MISSING_IMPORT = os.getenv('HACKING_VERBOSE_MISSING_IMPORT', 'False')


# Monkey patch broken excluded filter in pep8
# See https://github.com/jcrocholl/pep8/pull/111
def excluded(self, filename):
    """
    Check if options.exclude contains a pattern that matches filename.
    """
    basename = os.path.basename(filename)
    return any((pep8.filename_match(filename, self.options.exclude,
                                    default=False),
                pep8.filename_match(basename, self.options.exclude,
                                    default=False)))


def input_dir(self, dirname):
    """Check all files in this directory and all subdirectories."""
    dirname = dirname.rstrip('/')
    if self.excluded(dirname):
        return 0
    counters = self.options.report.counters
    verbose = self.options.verbose
    filepatterns = self.options.filename
    runner = self.runner
    for root, dirs, files in os.walk(dirname):
        if verbose:
            print('directory ' + root)
        counters['directories'] += 1
        for subdir in sorted(dirs):
            if self.excluded(os.path.join(root, subdir)):
                dirs.remove(subdir)
        for filename in sorted(files):
            # contain a pattern that matches?
            if ((pep8.filename_match(filename, filepatterns) and
                 not self.excluded(filename))):
                runner(os.path.join(root, filename))


def is_import_exception(mod):
    return (mod in IMPORT_EXCEPTIONS or
            any(mod.startswith(m + '.') for m in IMPORT_EXCEPTIONS))


def import_normalize(line):
    # convert "from x import y" to "import x.y"
    # handle "from x import y as z" to "import x.y as z"
    split_line = line.split()
    if ("import" in line and line.startswith("from ") and "," not in line and
        split_line[2] == "import" and split_line[3] != "*" and
        split_line[1] != "__future__" and
       (len(split_line) == 4 or
       (len(split_line) == 6 and split_line[4] == "as"))):
        return "import %s.%s" % (split_line[1], split_line[3])
    else:
        return line


def tempest_todo_format(physical_line):
    """Check for 'TODO()'.

    tempest HACKING guide recommendation for TODO:
    Include your name with TODOs as in "#TODO(termie)"
    T101
    """
    pos = physical_line.find('TODO')
    pos1 = physical_line.find('TODO(')
    pos2 = physical_line.find('#')  # make sure it's a comment
    if (pos != pos1 and pos2 >= 0 and pos2 < pos):
        return pos, "T101: Use TODO(NAME)"


def tempest_except_format(logical_line):
    """Check for 'except:'.

    tempest HACKING guide recommends not using except:
    Do not write "except:", use "except Exception:" at the very least
    T201
    """
    if logical_line.startswith("except:"):
        yield 6, "T201: no 'except:' at least use 'except Exception:'"


def tempest_except_format_assert(logical_line):
    """Check for 'assertRaises(Exception'.

    tempest HACKING guide recommends not using assertRaises(Exception...):
    Do not use overly broad Exception type
    T202
    """
    if logical_line.startswith("self.assertRaises(Exception"):
        yield 1, "T202: assertRaises Exception too broad"


def tempest_one_import_per_line(logical_line):
    """Check for import format.

    tempest HACKING guide recommends one import per line:
    Do not import more than one module per line

    Examples:
    BAD: from tempest.common.rest_client import RestClient, RestClientXML
    T301
    """
    pos = logical_line.find(',')
    parts = logical_line.split()
    if (pos > -1 and (parts[0] == "import" or
                      parts[0] == "from" and parts[2] == "import") and
        not is_import_exception(parts[1])):
        yield pos, "T301: one import per line"

_missingImport = set([])


def tempest_import_module_only(logical_line):
    """Check for import module only.

    tempest HACKING guide recommends importing only modules:
    Do not import objects, only modules
    T302 import only modules
    T303 Invalid Import
    T304 Relative Import
    """
    def importModuleCheck(mod, parent=None, added=False):
        """
        If can't find module on first try, recursively check for relative
        imports
        """
        current_path = os.path.dirname(pep8.current_file)
        try:
            with warnings.catch_warnings():
                warnings.simplefilter('ignore', DeprecationWarning)
                valid = True
                if parent:
                    if is_import_exception(parent):
                        return
                    parent_mod = __import__(parent, globals(), locals(),
                                            [mod], -1)
                    valid = inspect.ismodule(getattr(parent_mod, mod))
                else:
                    __import__(mod, globals(), locals(), [], -1)
                    valid = inspect.ismodule(sys.modules[mod])
                if not valid:
                    if added:
                        sys.path.pop()
                        added = False
                        return logical_line.find(mod), ("T304: No "
                                                        "relative  imports. "
                                                        "'%s' is a relative "
                                                        "import"
                                                        % logical_line)
                    return logical_line.find(mod), ("T302: import only"
                                                    " modules. '%s' does not "
                                                    "import a module"
                                                    % logical_line)

        except (ImportError, NameError) as exc:
            if not added:
                added = True
                sys.path.append(current_path)
                return importModuleCheck(mod, parent, added)
            else:
                name = logical_line.split()[1]
                if name not in _missingImport:
                    if VERBOSE_MISSING_IMPORT != 'False':
                        print >> sys.stderr, ("ERROR: import '%s' in %s "
                                              "failed: %s" %
                                              (name, pep8.current_file, exc))
                    _missingImport.add(name)
                added = False
                sys.path.pop()
                return

        except AttributeError:
            # Invalid import
            return logical_line.find(mod), ("T303: Invalid import, "
                                            "AttributeError raised")

    # convert "from x import y" to " import x.y"
    # convert "from x import y as z" to " import x.y"
    import_normalize(logical_line)
    split_line = logical_line.split()

    if (logical_line.startswith("import ") and "," not in logical_line and
            (len(split_line) == 2 or
            (len(split_line) == 4 and split_line[2] == "as"))):
        mod = split_line[1]
        rval = importModuleCheck(mod)
        if rval is not None:
            yield rval

    # TODO(jogo) handle "from x import *"

#TODO(jogo): import template: T305


def tempest_import_alphabetical(logical_line, line_number, lines):
    """Check for imports in alphabetical order.

    Tempest HACKING guide recommendation for imports:
    imports in human alphabetical order
    T306
    """
    # handle import x
    # use .lower since capitalization shouldn't dictate order
    split_line = import_normalize(logical_line.strip()).lower().split()
    split_previous = import_normalize(lines[
                                      line_number - 2]).strip().lower().split()
    # with or without "as y"
    length = [2, 4]
    if (len(split_line) in length and len(split_previous) in length and
        split_line[0] == "import" and split_previous[0] == "import"):
        if split_line[1] < split_previous[1]:
            yield (0, "T306: imports not in alphabetical order"
                      " (%s, %s)"
                      % (split_previous[1], split_line[1]))


def tempest_docstring_start_space(physical_line):
    """Check for docstring not start with space.

    tempest HACKING guide recommendation for docstring:
    Docstring should not start with space
    T401
    """
    pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])  # start
    end = max([physical_line[-4:-1] == i for i in DOCSTRING_TRIPLE])  # end
    if (pos != -1 and end and len(physical_line) > pos + 4):
        if (physical_line[pos + 3] == ' '):
            return (pos, "T401: one line docstring should not start"
                         " with a space")


def tempest_docstring_one_line(physical_line):
    """Check one line docstring end.

    tempest HACKING guide recommendation for one line docstring:
    A one line docstring looks like this and ends in a period.
    T402
    """
    pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])  # start
    end = max([physical_line[-4:-1] == i for i in DOCSTRING_TRIPLE])  # end
    if (pos != -1 and end and len(physical_line) > pos + 4):
        if (physical_line[-5] != '.'):
            return pos, "T402: one line docstring needs a period"


def tempest_docstring_multiline_end(physical_line):
    """Check multi line docstring end.

    Tempest HACKING guide recommendation for docstring:
    Docstring should end on a new line
    T403
    """
    pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])  # start
    if (pos != -1 and len(physical_line) == pos):
        if (physical_line[pos + 3] == ' '):
            return (pos, "T403: multi line docstring end on new line")


def tempest_no_test_docstring(physical_line, previous_logical, filename):
    """Check that test_ functions don't have docstrings

    This ensure we get better results out of tempest, instead
    of them being hidden behind generic descriptions of the
    functions.

    T404
    """
    if "tempest/test" in filename:
        pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])
        if pos != -1:
            if previous_logical.startswith("def test_"):
                return (pos, "T404: test functions must "
                        "not have doc strings")

SKIP_DECORATOR = '@testtools.skip('


def tempest_skip_bugs(physical_line):
    """Check skip lines for proper bug entries

    T601: Bug not in skip line
    T602: Bug in message formatted incorrectly
    """

    pos = physical_line.find(SKIP_DECORATOR)

    skip_re = re.compile(r'^\s*@testtools.skip.*')

    if pos != -1 and skip_re.match(physical_line):
        bug = re.compile(r'^.*\bbug\b.*', re.IGNORECASE)
        if bug.match(physical_line) is None:
            return (pos, 'T601: skips must have an associated bug')

        bug_re = re.compile(r'.*skip\(.*Bug\s\#\d+', re.IGNORECASE)

        if bug_re.match(physical_line) is None:
            return (pos, 'T602: Bug number formatted incorrectly')


FORMAT_RE = re.compile("%(?:"
                       "%|"           # Ignore plain percents
                       "(\(\w+\))?"   # mapping key
                       "([#0 +-]?"    # flag
                       "(?:\d+|\*)?"  # width
                       "(?:\.\d+)?"   # precision
                       "[hlL]?"       # length mod
                       "\w))")        # type


class LocalizationError(Exception):
    pass


def check_i18n():
    """Generator that checks token stream for localization errors.

    Expects tokens to be ``send``ed one by one.
    Raises LocalizationError if some error is found.
    """
    while True:
        try:
            token_type, text, _, _, line = yield
        except GeneratorExit:
            return
        if (token_type == tokenize.NAME and text == "_" and
            not line.startswith('def _(msg):')):

            while True:
                token_type, text, start, _, _ = yield
                if token_type != tokenize.NL:
                    break
            if token_type != tokenize.OP or text != "(":
                continue  # not a localization call

            format_string = ''
            while True:
                token_type, text, start, _, _ = yield
                if token_type == tokenize.STRING:
                    format_string += eval(text)
                elif token_type == tokenize.NL:
                    pass
                else:
                    break

            if not format_string:
                raise LocalizationError(start,
                                        "T701: Empty localization "
                                        "string")
            if token_type != tokenize.OP:
                raise LocalizationError(start,
                                        "T701: Invalid localization "
                                        "call")
            if text != ")":
                if text == "%":
                    raise LocalizationError(start,
                                            "T702: Formatting "
                                            "operation should be outside"
                                            " of localization method call")
                elif text == "+":
                    raise LocalizationError(start,
                                            "T702: Use bare string "
                                            "concatenation instead of +")
                else:
                    raise LocalizationError(start,
                                            "T702: Argument to _ must"
                                            " be just a string")

            format_specs = FORMAT_RE.findall(format_string)
            positional_specs = [(key, spec) for key, spec in format_specs
                                if not key and spec]
            # not spec means %%, key means %(smth)s
            if len(positional_specs) > 1:
                raise LocalizationError(start,
                                        "T703: Multiple positional "
                                        "placeholders")


def tempest_localization_strings(logical_line, tokens):
    """Check localization in line.

    T701: bad localization call
    T702: complex expression instead of string as argument to _()
    T703: multiple positional placeholders
    """

    gen = check_i18n()
    next(gen)
    try:
        map(gen.send, tokens)
        gen.close()
    except LocalizationError as e:
        yield e.args

#TODO(jogo) Dict and list objects

current_file = ""


def readlines(filename):
    """Record the current file being tested."""
    pep8.current_file = filename
    return open(filename).readlines()


def add_tempest():
    """Monkey patch in tempest guidelines.

    Look for functions that start with tempest_  and have arguments
    and add them to pep8 module
    Assumes you know how to write pep8.py checks
    """
    for name, function in globals().items():
        if not inspect.isfunction(function):
            continue
        args = inspect.getargspec(function)[0]
        if args and name.startswith("tempest"):
            exec("pep8.%s = %s" % (name, name))


def once_git_check_commit_title():
    """Check git commit messages.

    tempest HACKING recommends not referencing a bug or blueprint
    in first line, it should provide an accurate description of the change
    T801
    T802 Title limited to 50 chars
    """
    #Get title of most recent commit

    subp = subprocess.Popen(['git', 'log', '--no-merges', '--pretty=%s', '-1'],
                            stdout=subprocess.PIPE)
    title = subp.communicate()[0]
    if subp.returncode:
        raise Exception("git log failed with code %s" % subp.returncode)

    #From https://github.com/openstack/openstack-ci-puppet
    #       /blob/master/modules/gerrit/manifests/init.pp#L74
    #Changeid|bug|blueprint
    git_keywords = (r'(I[0-9a-f]{8,40})|'
                    '([Bb]ug|[Ll][Pp])[\s\#:]*(\d+)|'
                    '([Bb]lue[Pp]rint|[Bb][Pp])[\s\#:]*([A-Za-z0-9\\-]+)')
    GIT_REGEX = re.compile(git_keywords)

    error = False
    #NOTE(jogo) if match regex but over 3 words, acceptable title
    if GIT_REGEX.search(title) is not None and len(title.split()) <= 3:
        print ("T801: git commit title ('%s') should provide an accurate "
               "description of the change, not just a reference to a bug "
               "or blueprint" % title.strip())
        error = True
    if len(title.decode('utf-8')) > 72:
        print ("T802: git commit title ('%s') should be under 50 chars"
               % title.strip())
        error = True
    return error

if __name__ == "__main__":
    #include tempest path
    sys.path.append(os.getcwd())
    #Run once tests (not per line)
    once_error = once_git_check_commit_title()
    #TEMPEST error codes start with a T
    pep8.ERRORCODE_REGEX = re.compile(r'[EWT]\d{3}')
    add_tempest()
    pep8.current_file = current_file
    pep8.readlines = readlines
    pep8.StyleGuide.excluded = excluded
    pep8.StyleGuide.input_dir = input_dir
    try:
        pep8._main()
        sys.exit(once_error)
    finally:
        if len(_missingImport) > 0:
            print >> sys.stderr, ("%i imports missing in this test environment"
                                  % len(_missingImport))
