#!/usr/bin/env python
#     Copyright 2014, Kay Hayen, mailto:kay.hayen@gmail.com
#
#     Part of "Nuitka", an optimizing Python compiler that is compatible and
#     integrates with CPython, but also works on its own.
#
#     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.
#

# Disabled globally:
#
# W0232: Class has no __init__ method
# Who cares, I am using overrides that don't need to change object init a lot
# and I rarely ever made a mistake with forgetting to call __init__ of the
# parent.
#
# I0011: Locally disabling W....
# Strange one anyway, I want to locally disable stuff. And that just makes it
# a different warning. Amazing. Luckily I can decide to ignore that globally
# then.
#
# E1120 / E1123: Constructor call checks frequently fail miserably.
#
# E1103: Instance of 'x' has no 'y' member but some types could not be inferred
#
# W0632: Possible unbalanced tuple unpacking with sequence defined at
#
import sys, os, subprocess

# Go its own directory, to have it easy with path knowledge.
os.chdir(os.path.dirname(os.path.abspath( __file__ )))
os.chdir("..")

pylint_options = """
--rcfile=/dev/null
--disable=I0011,W0232,C0326,C0330,W0120,C1001,E1120,E1123,E1103,W0632
--msg-template="{path}:{line} {msg_id} {obj} {msg}"
--reports=no
--persistent=no
--method-rgx=[a-z_][a-zA-Z0-9_]{2,40}$
--module-rgx=.*
--function-rgx=.*
--variable-rgx=.*
--argument-rgx=.*
--dummy-variables-rgx=_.*
--const-rgx=.*
--max-line-length=120
--no-docstring-rgx=.*
--max-module-lines=5000
--min-public-methods=0
--max-public-methods=100
--max-args=10
--max-parents=10
""".split()


from optparse import OptionParser

parser = OptionParser()

parser.add_option(
    "--hide-todos", "--no-todos",
    action  = "store_true",
    dest    = "no_todos",
    default = False,
    help    = """\
    Default is %default."""
)

options, positional_args = parser.parse_args()

if os.environ.get("TODO", 0) or options.no_todos:
    pylint_options.append("--notes=")

blacklist = (
    "oset.py",
    "odict.py",
    "SyntaxHighlighting.py",
    "TreeDisplay.py"
)

def executePyLint( filename ):
    command = "pylint %s %s %s" % (
        " ".join(pylint_options),
        os.environ.get("PYLINT_EXTRA_OPTIONS", ""),
        filename
    )

    process = subprocess.Popen(
        args   = command,
        stdout = subprocess.PIPE,
        stderr = subprocess.STDOUT,
        shell  = True
    )

    stdout, _stderr = process.communicate()
    exit_code = process.returncode

    assert not _stderr
    if stdout:
        for line in stdout.split(b"\n"):
            output = line.decode()

            print(output)

    sys.stdout.flush()

if "PYTHONPATH" not in os.environ:
    os.environ[ "PYTHONPATH" ] = "."

if positional_args:
    for positional_arg in positional_args:
        executePyLint(positional_arg)
else:
    executePyLint("bin/nuitka")

    for dirpath, dirnames, filenames in os.walk("nuitka"):
        dirnames.sort()

        if "inline_copy" in dirnames:
            dirnames.remove("inline_copy")

        filenames.sort()

        for filename in filenames:
            if not filename.endswith(".py"):
                continue

            # Skip temporary files from flymake mode of Emacs.
            if filename.endswith("_flymake.py"):
                continue

            # Skip temporary files from unsaved files of Emacs.
            if filename.startswith(".#"):
                continue

            if filename not in blacklist:
                executePyLint(
                    os.path.join(dirpath, filename)
                )
