"""Fixer for lib2to3 that inserts mypy annotations into all methods.

The simplest way to run this is to copy it into lib2to3's "fixes"
subdirectory and then run "2to3 -f annotate" over your files.

The fixer transforms e.g.

  def foo(self, bar, baz=12):
      return bar + baz

into

  def foo(self, bar, baz=12):
      # type: (Any, int) -> Any
      return bar + baz

It does not do type inference but it recognizes some basic default
argument values such as numbers and strings (and assumes their type
implies the argument type).

It also uses some basic heuristics to decide whether to ignore the
first argument:

  - always if it's named 'self'
  - if there's a @classmethod decorator

Finally, it knows that __init__() is supposed to return None.
"""

from __future__ import annotations

import os
import re
from lib2to3.fixer_base import BaseFix
from lib2to3.fixer_util import syms, token, touch_import
from lib2to3.patcomp import compile_pattern
from lib2to3.pytree import Leaf, Node


class FixAnnotate(BaseFix):
    # This fixer is compatible with the bottom matcher.
    BM_compatible = True

    # This fixer shouldn't run by default.
    explicit = True

    # The pattern to match.
    PATTERN = """
              funcdef< 'def' name=any parameters< '(' [args=any] ')' > ':' suite=any+ >
              """

    counter = None if not os.getenv("MAXFIXES") else int(os.getenv("MAXFIXES"))

    def transform(self, node, results):
        if FixAnnotate.counter is not None:
            if FixAnnotate.counter <= 0:
                return
        suite = results["suite"]
        children = suite[0].children

        # NOTE: I've reverse-engineered the structure of the parse tree.
        # It's always a list of nodes, the first of which contains the
        # entire suite.  Its children seem to be:
        #
        #   [0] NEWLINE
        #   [1] INDENT
        #   [2...n-2] statements (the first may be a docstring)
        #   [n-1] DEDENT
        #
        # Comments before the suite are part of the INDENT's prefix.
        #
        # "Compact" functions (e.g. "def foo(x, y): return max(x, y)")
        # have a different structure that isn't matched by PATTERN.
        #
        #   print('-'*60)
        #   print(node)
        #   for i, ch in enumerate(children):
        #       print(i, repr(ch.prefix), repr(ch))
        #
        # Check if there's already an annotation.
        for ch in children:
            if ch.prefix.lstrip().startswith("# type:"):
                return  # There's already a # type: comment here; don't change anything.

        # Compute the annotation
        annot = self.make_annotation(node, results)

        # Insert '# type: {annot}' comment.
        # For reference, see lib2to3/fixes/fix_tuple_params.py in stdlib.
        if len(children) >= 2 and children[1].type == token.INDENT:
            children[1].prefix = "{}# type: {}\n{}".format(
                children[1].value, annot, children[1].prefix
            )
            children[1].changed()
            if FixAnnotate.counter is not None:
                FixAnnotate.counter -= 1

        # Also add 'from typing import Any' at the top.
        if "Any" in annot:
            touch_import("typing", "Any", node)

    def make_annotation(self, node, results):
        name = results["name"]
        assert isinstance(name, Leaf), repr(name)
        assert name.type == token.NAME, repr(name)
        decorators = self.get_decorators(node)
        is_method = self.is_method(node)
        if name.value == "__init__" or not self.has_return_exprs(node):
            restype = "None"
        else:
            restype = "Any"
        args = results.get("args")
        argtypes = []
        if isinstance(args, Node):
            children = args.children
        elif isinstance(args, Leaf):
            children = [args]
        else:
            children = []
        # Interpret children according to the following grammar:
        # (('*'|'**')? NAME ['=' expr] ','?)*
        stars = inferred_type = ""
        in_default = False
        at_start = True
        for child in children:
            if isinstance(child, Leaf):
                if child.value in ("*", "**"):
                    stars += child.value
                elif child.type == token.NAME and not in_default:
                    if not is_method or not at_start or "staticmethod" in decorators:
                        inferred_type = "Any"
                    else:
                        # Always skip the first argument if it's named 'self'.
                        # Always skip the first argument of a class method.
                        if child.value == "self" or "classmethod" in decorators:
                            pass
                        else:
                            inferred_type = "Any"
                elif child.value == "=":
                    in_default = True
                elif in_default and child.value != ",":
                    if child.type == token.NUMBER:
                        if re.match(r"\d+[lL]?$", child.value):
                            inferred_type = "int"
                        else:
                            inferred_type = "float"  # TODO: complex?
                    elif child.type == token.STRING:
                        if child.value.startswith(("u", "U")):
                            inferred_type = "unicode"
                        else:
                            inferred_type = "str"
                    elif child.type == token.NAME and child.value in ("True", "False"):
                        inferred_type = "bool"
                elif child.value == ",":
                    if inferred_type:
                        argtypes.append(stars + inferred_type)
                    # Reset
                    stars = inferred_type = ""
                    in_default = False
                    at_start = False
        if inferred_type:
            argtypes.append(stars + inferred_type)
        return "(" + ", ".join(argtypes) + ") -> " + restype

    # The parse tree has a different shape when there is a single
    # decorator vs. when there are multiple decorators.
    DECORATED = "decorated< (d=decorator | decorators< dd=decorator+ >) funcdef >"
    decorated = compile_pattern(DECORATED)

    def get_decorators(self, node):
        """Return a list of decorators found on a function definition.

        This is a list of strings; only simple decorators
        (e.g. @staticmethod) are returned.

        If the function is undecorated or only non-simple decorators
        are found, return [].
        """
        if node.parent is None:
            return []
        results = {}
        if not self.decorated.match(node.parent, results):
            return []
        decorators = results.get("dd") or [results["d"]]
        decs = []
        for d in decorators:
            for child in d.children:
                if isinstance(child, Leaf) and child.type == token.NAME:
                    decs.append(child.value)
        return decs

    def is_method(self, node):
        """Return whether the node occurs (directly) inside a class."""
        node = node.parent
        while node is not None:
            if node.type == syms.classdef:
                return True
            if node.type == syms.funcdef:
                return False
            node = node.parent
        return False

    RETURN_EXPR = "return_stmt< 'return' any >"
    return_expr = compile_pattern(RETURN_EXPR)

    def has_return_exprs(self, node):
        """Traverse the tree below node looking for 'return expr'.

        Return True if at least 'return expr' is found, False if not.
        (If both 'return' and 'return expr' are found, return True.)
        """
        results = {}
        if self.return_expr.match(node, results):
            return True
        return any(
            child.type not in (syms.funcdef, syms.classdef) and self.has_return_exprs(child)
            for child in node.children
        )
