# 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.


# This is very-very-very simple linter made in one evening without thoughts of
# making something great, but just a thing that works.

import os
import re


RULES = []
HAS_ERRORS = False
IGNORE_ERROR = False


def error_report(file, line, msg, _state=[]):
    global HAS_ERRORS, IGNORE_ERROR
    if IGNORE_ERROR:
        return
    if _state and _state[0] == file.name:
        pass
    else:
        if _state:
            _state[0] = file.name
        else:
            _state.append(file.name)
        sys.stderr.write(file.name + "\n")
    sys.stderr.write(" ".join(["  line", str(line), ":", msg]) + "\n")
    HAS_ERRORS = True


def register_rule(func):
    RULES.append(func)
    return func


def main(path):
    for file in iter_rst_files(os.path.abspath(path)):
        validate(file)
    sys.exit(HAS_ERRORS)


def iter_rst_files(path):
    if os.path.isfile(path):
        with open(path) as f:
            yield f
        return
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith(".rst"):
                with open(os.path.join(root, file), "rb") as f:
                    yield f


def validate(file):
    global IGNORE_ERROR
    IGNORE_ERROR = False
    rules = [rule(file) for rule in RULES]
    for rule in rules:
        for _ in rule:
            # initialize coroutine
            break
    while True:
        line = file.readline().decode("utf-8")
        exhausted = []
        for idx, rule in enumerate(rules):
            try:
                error = rule.send(line)
            except StopIteration:
                exhausted.append(rule)
            else:
                if error:
                    error_report(*error)

        # not very optimal, but I'm lazy to figure anything better
        for rule in exhausted:
            rules.pop(rules.index(rule))

        if not line:
            break


@register_rule
def silent_scream(file):
    """Sometimes we must accept presence of some errors by some relevant
    reasons. Here we're doing that."""
    global IGNORE_ERROR
    counter = 0
    while True:
        line = yield None
        if not line:
            break

        if counter:
            IGNORE_ERROR = True
            counter -= 1
        else:
            IGNORE_ERROR = False

        match = re.match(r"\s*.. lint: ignore errors for the next (\d+) line?", line)
        if match:
            # +1 for empty line right after comment
            counter = int(match.group(1)) + 1


@register_rule
def license_adviser(file):
    """Each source file must include ASF license header."""
    header = iter(
        """
.. 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.

""".lstrip().splitlines(
            False
        )
    )
    error = None
    for n, hline in enumerate(header):
        fline = yield error
        error = None
        if hline != fline.strip("\r\n"):
            error = (
                file,
                n + 1,
                "bad ASF license header\n"
                "  expected: {0}\n"
                "  found:    {1}".format(hline, fline.strip()),
            )


@register_rule
def whitespace_committee(file):
    """Whitespace committee takes care about whitespace (surprise!) characters
    in files. The documentation style guide says:

    - There should be no trailing white space;
    - More than one empty line is not allowed and there shouldn't be such
      at the end of file;
    - The last line should ends with newline character

    Additionally it alerts about tabs if they were used instead of spaces.

    TODO: check for indentation
    """
    error = prev = None
    n = 0
    while True:
        line = yield error
        error = None
        if not line:
            break
        n += 1

        # Check for trailing whitespace
        if line.strip("\r\n").endswith(" "):
            error = (file, n + 1, "trailing whitespace detected!\n" "{0}".format(line))

        # Check for continuous empty lines
        if prev is not None:
            if prev.strip() == line.strip() == "":
                error = (file, n + 1, "too many empty lines")

        # Nobody loves tabs-spaces cocktail, we prefer spaces
        if "\t" in line:
            error = (file, n + 1, "no tabs please")

        prev = line

    # Accidentally empty file committed?
    if prev is None:
        error = (file, 0, "oh no! file seems empty!")

    # Empty last lines not welcome
    elif prev.strip() == "":
        error = (file, n + 1, "no empty last lines please")

    # Last line should ends with newline character
    elif not prev.endswith("\n"):
        error = (file, n + 1, "last line should ends with newline character")

    yield error
    return


@register_rule
def line_length_checker(file):
    """Use a modern max line length of 90 chars, as recommended by things like
    https://github.com/ambv/black and https://youtu.be/wf-BqAjZb8M?t=260 .
    """
    in_code_block = False
    seen_emptyline = False
    n = 0
    error = None
    while True:
        line = yield error
        error = None
        if not line:
            break
        n += 1
        line = line.rstrip()

        # We have to ignore stuff in code blocks since it's hard to keep it
        # within 90 chars wide box.
        if line.strip().startswith(".. code") or line.endswith("::"):
            in_code_block = True
            continue

        # Check for line length unless we're not in code block
        if len(line) > 90 and not in_code_block:
            if line.startswith(".."):
                # Ignore long lines with external links
                continue

            if line.endswith(">`_") or line.endswith(">`"):
                # Ignore long lines because of URLs
                # TODO: need to be more smart here
                continue

            error = (
                file,
                n + 1,
                "too long ({0} > 90) line\n{1}\n" "".format(len(line), line),
            )

        # Empty lines are acts as separators for code block content
        elif not line:
            seen_emptyline = True

        # So if we saw an empty line and here goes content without indentation,
        # so it mostly have to sign about the end of our code block
        # (if it ever occurs)
        elif seen_emptyline and line and not line.startswith(" "):
            seen_emptyline = False
            in_code_block = False

        else:
            seen_emptyline = False


@register_rule
def my_lovely_hat(file):
    """Everyone loves to wear a nice hat on they head, so articles does too."""
    error = None
    n = 0
    while True:
        line = yield error
        error = None
        if not line:
            break

        line = line.strip()

        if not line:
            continue

        if line.startswith(".."):
            continue

        if set(line) < set(["#", "-", "=", "*"]):
            break
        else:
            lines = [line, "\n", (yield None), (yield None)]
            yield (file, n + 1, "bad title header:\n" "{}".format("".join(lines)))
            return


if __name__ == "__main__":
    import sys

    if len(sys.argv) == 1:
        sys.stderr.write("Argument with the target path is missed")
        sys.exit(2)
    main(sys.argv[1])
