# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt

"""Find functions and classes in Python code."""

from __future__ import annotations

import ast
import dataclasses
from typing import cast

from coverage.plugin import CodeRegion


@dataclasses.dataclass
class Context:
    """The nested named context of a function or class."""

    name: str
    kind: str
    lines: set[int]


class RegionFinder:
    """An ast visitor that will find and track regions of code.

    Functions and classes are tracked by name. Results are in the .regions
    attribute.

    """

    def __init__(self) -> None:
        self.regions: list[CodeRegion] = []
        self.context: list[Context] = []

    def parse_source(self, source: str) -> None:
        """Parse `source` and walk the ast to populate the .regions attribute."""
        self.handle_node(ast.parse(source))

    def fq_node_name(self) -> str:
        """Get the current fully qualified name we're processing."""
        return ".".join(c.name for c in self.context)

    def handle_node(self, node: ast.AST) -> None:
        """Recursively handle any node."""
        if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
            self.handle_FunctionDef(node)
        elif isinstance(node, ast.ClassDef):
            self.handle_ClassDef(node)
        else:
            self.handle_node_body(node)

    def handle_node_body(self, node: ast.AST) -> None:
        """Recursively handle the nodes in this node's body, if any."""
        for body_node in getattr(node, "body", ()):
            self.handle_node(body_node)

    def handle_FunctionDef(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None:
        """Called for `def` or `async def`."""
        lines = set(range(node.body[0].lineno, cast(int, node.body[-1].end_lineno) + 1))
        if self.context and self.context[-1].kind == "class":
            # Function bodies are part of their enclosing class.
            self.context[-1].lines |= lines
        # Function bodies should be excluded from the nearest enclosing function.
        for ancestor in reversed(self.context):
            if ancestor.kind == "function":
                ancestor.lines -= lines
                break
        self.context.append(Context(node.name, "function", lines))
        self.regions.append(
            CodeRegion(
                kind="function",
                name=self.fq_node_name(),
                start=node.lineno,
                lines=lines,
            )
        )
        self.handle_node_body(node)
        self.context.pop()

    def handle_ClassDef(self, node: ast.ClassDef) -> None:
        """Called for `class`."""
        # The lines for a class are the lines in the methods of the class.
        # We start empty, and count on visit_FunctionDef to add the lines it
        # finds.
        lines: set[int] = set()
        self.context.append(Context(node.name, "class", lines))
        self.regions.append(
            CodeRegion(
                kind="class",
                name=self.fq_node_name(),
                start=node.lineno,
                lines=lines,
            )
        )
        self.handle_node_body(node)
        self.context.pop()
        # Class bodies should be excluded from the enclosing classes.
        for ancestor in reversed(self.context):
            if ancestor.kind == "class":
                ancestor.lines -= lines


def code_regions(source: str) -> list[CodeRegion]:
    """Find function and class regions in source code.

    Analyzes the code in `source`, and returns a list of :class:`CodeRegion`
    objects describing functions and classes as regions of the code::

        [
            CodeRegion(kind="function", name="func1", start=8, lines={10, 11, 12}),
            CodeRegion(kind="function", name="MyClass.method", start=30, lines={34, 35, 36}),
            CodeRegion(kind="class", name="MyClass", start=25, lines={34, 35, 36}),
        ]

    The line numbers will include comments and blank lines.  Later processing
    will need to ignore those lines as needed.

    Nested functions and classes are excluded from their enclosing region.  No
    line should be reported as being part of more than one function, or more
    than one class.  Lines in methods are reported as being in a function and
    in a class.

    """
    rf = RegionFinder()
    rf.parse_source(source)
    return rf.regions
