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

"""
.. versionadded:: 4.0

Plug-in interfaces for coverage.py.

Coverage.py supports a few different kinds of plug-ins that change its
behavior:

* File tracers implement tracing of non-Python file types.

* Configurers add custom configuration, using Python code to change the
  configuration.

* Dynamic context switchers decide when the dynamic context has changed, for
  example, to record what test function produced the coverage.

To write a coverage.py plug-in, create a module with a subclass of
:class:`~coverage.CoveragePlugin`.  You will override methods in your class to
participate in various aspects of coverage.py's processing.
Different types of plug-ins have to override different methods.

Any plug-in can optionally implement :meth:`~coverage.CoveragePlugin.sys_info`
to provide debugging information about their operation.

Your module must also contain a ``coverage_init`` function that registers an
instance of your plug-in class::

    import coverage

    class MyPlugin(coverage.CoveragePlugin):
        ...

    def coverage_init(reg, options):
        reg.add_file_tracer(MyPlugin())

You use the `reg` parameter passed to your ``coverage_init`` function to
register your plug-in object.  The registration method you call depends on
what kind of plug-in it is.

If your plug-in takes options, the `options` parameter is a dictionary of your
plug-in's options from the coverage.py configuration file.  Use them however
you want to configure your object before registering it.

Coverage.py will store its own information on your plug-in object, using
attributes whose names start with ``_coverage_``.  Don't be startled.

.. warning::
    Plug-ins are imported by coverage.py before it begins measuring code.
    If you write a plugin in your own project, it might import your product
    code before coverage.py can start measuring.  This can result in your
    own code being reported as missing.

    One solution is to put your plugins in your project tree, but not in
    your importable Python package.


.. _file_tracer_plugins:

File Tracers
============

File tracers implement measurement support for non-Python files.  File tracers
implement the :meth:`~coverage.CoveragePlugin.file_tracer` method to claim
files and the :meth:`~coverage.CoveragePlugin.file_reporter` method to report
on those files.

In your ``coverage_init`` function, use the ``add_file_tracer`` method to
register your file tracer.


.. _configurer_plugins:

Configurers
===========

.. versionadded:: 4.5

Configurers modify the configuration of coverage.py during start-up.
Configurers implement the :meth:`~coverage.CoveragePlugin.configure` method to
change the configuration.

In your ``coverage_init`` function, use the ``add_configurer`` method to
register your configurer.


.. _dynamic_context_plugins:

Dynamic Context Switchers
=========================

.. versionadded:: 5.0

Dynamic context switcher plugins implement the
:meth:`~coverage.CoveragePlugin.dynamic_context` method to dynamically compute
the context label for each measured frame.

Computed context labels are useful when you want to group measured data without
modifying the source code.

For example, you could write a plugin that checks `frame.f_code` to inspect
the currently executed method, and set the context label to a fully qualified
method name if it's an instance method of `unittest.TestCase` and the method
name starts with 'test'.  Such a plugin would provide basic coverage grouping
by test and could be used with test runners that have no built-in coveragepy
support.

In your ``coverage_init`` function, use the ``add_dynamic_context`` method to
register your dynamic context switcher.

"""

from __future__ import annotations

import dataclasses
import functools

from types import FrameType
from typing import Any, Iterable

from coverage import files
from coverage.misc import _needs_to_implement
from coverage.types import TArc, TConfigurable, TLineNo, TSourceTokenLines


class CoveragePlugin:
    """Base class for coverage.py plug-ins."""

    _coverage_plugin_name: str
    _coverage_enabled: bool

    def file_tracer(self, filename: str) -> FileTracer | None: # pylint: disable=unused-argument
        """Get a :class:`FileTracer` object for a file.

        Plug-in type: file tracer.

        Every Python source file is offered to your plug-in to give it a chance
        to take responsibility for tracing the file.  If your plug-in can
        handle the file, it should return a :class:`FileTracer` object.
        Otherwise return None.

        There is no way to register your plug-in for particular files.
        Instead, this method is invoked for all  files as they are executed,
        and the plug-in decides whether it can trace the file or not.
        Be prepared for `filename` to refer to all kinds of files that have
        nothing to do with your plug-in.

        The file name will be a Python file being executed.  There are two
        broad categories of behavior for a plug-in, depending on the kind of
        files your plug-in supports:

        * Static file names: each of your original source files has been
          converted into a distinct Python file.  Your plug-in is invoked with
          the Python file name, and it maps it back to its original source
          file.

        * Dynamic file names: all of your source files are executed by the same
          Python file.  In this case, your plug-in implements
          :meth:`FileTracer.dynamic_source_filename` to provide the actual
          source file for each execution frame.

        `filename` is a string, the path to the file being considered.  This is
        the absolute real path to the file.  If you are comparing to other
        paths, be sure to take this into account.

        Returns a :class:`FileTracer` object to use to trace `filename`, or
        None if this plug-in cannot trace this file.

        """
        return None

    def file_reporter(
        self,
        filename: str,                  # pylint: disable=unused-argument
    ) -> FileReporter | str:      # str should be Literal["python"]
        """Get the :class:`FileReporter` class to use for a file.

        Plug-in type: file tracer.

        This will only be invoked if `filename` returns non-None from
        :meth:`file_tracer`.  It's an error to return None from this method.

        Returns a :class:`FileReporter` object to use to report on `filename`,
        or the string `"python"` to have coverage.py treat the file as Python.

        """
        _needs_to_implement(self, "file_reporter")

    def dynamic_context(
        self,
        frame: FrameType,               # pylint: disable=unused-argument
    ) -> str | None:
        """Get the dynamically computed context label for `frame`.

        Plug-in type: dynamic context.

        This method is invoked for each frame when outside of a dynamic
        context, to see if a new dynamic context should be started.  If it
        returns a string, a new context label is set for this and deeper
        frames.  The dynamic context ends when this frame returns.

        Returns a string to start a new dynamic context, or None if no new
        context should be started.

        """
        return None

    def find_executable_files(
        self,
        src_dir: str,                   # pylint: disable=unused-argument
    ) -> Iterable[str]:
        """Yield all of the executable files in `src_dir`, recursively.

        Plug-in type: file tracer.

        Executability is a plug-in-specific property, but generally means files
        which would have been considered for coverage analysis, had they been
        included automatically.

        Returns or yields a sequence of strings, the paths to files that could
        have been executed, including files that had been executed.

        """
        return []

    def configure(self, config: TConfigurable) -> None:
        """Modify the configuration of coverage.py.

        Plug-in type: configurer.

        This method is called during coverage.py start-up, to give your plug-in
        a chance to change the configuration.  The `config` parameter is an
        object with :meth:`~coverage.Coverage.get_option` and
        :meth:`~coverage.Coverage.set_option` methods.  Do not call any other
        methods on the `config` object.

        """
        pass

    def sys_info(self) -> Iterable[tuple[str, Any]]:
        """Get a list of information useful for debugging.

        Plug-in type: any.

        This method will be invoked for ``--debug=sys``.  Your
        plug-in can return any information it wants to be displayed.

        Returns a list of pairs: `[(name, value), ...]`.

        """
        return []


class CoveragePluginBase:
    """Plugins produce specialized objects, which point back to the original plugin."""
    _coverage_plugin: CoveragePlugin


class FileTracer(CoveragePluginBase):
    """Support needed for files during the execution phase.

    File tracer plug-ins implement subclasses of FileTracer to return from
    their :meth:`~CoveragePlugin.file_tracer` method.

    You may construct this object from :meth:`CoveragePlugin.file_tracer` any
    way you like.  A natural choice would be to pass the file name given to
    `file_tracer`.

    `FileTracer` objects should only be created in the
    :meth:`CoveragePlugin.file_tracer` method.

    See :ref:`howitworks` for details of the different coverage.py phases.

    """

    def source_filename(self) -> str:
        """The source file name for this file.

        This may be any file name you like.  A key responsibility of a plug-in
        is to own the mapping from Python execution back to whatever source
        file name was originally the source of the code.

        See :meth:`CoveragePlugin.file_tracer` for details about static and
        dynamic file names.

        Returns the file name to credit with this execution.

        """
        _needs_to_implement(self, "source_filename")

    def has_dynamic_source_filename(self) -> bool:
        """Does this FileTracer have dynamic source file names?

        FileTracers can provide dynamically determined file names by
        implementing :meth:`dynamic_source_filename`.  Invoking that function
        is expensive. To determine whether to invoke it, coverage.py uses the
        result of this function to know if it needs to bother invoking
        :meth:`dynamic_source_filename`.

        See :meth:`CoveragePlugin.file_tracer` for details about static and
        dynamic file names.

        Returns True if :meth:`dynamic_source_filename` should be called to get
        dynamic source file names.

        """
        return False

    def dynamic_source_filename(
        self,
        filename: str,                  # pylint: disable=unused-argument
        frame: FrameType,               # pylint: disable=unused-argument
    ) -> str | None:
        """Get a dynamically computed source file name.

        Some plug-ins need to compute the source file name dynamically for each
        frame.

        This function will not be invoked if
        :meth:`has_dynamic_source_filename` returns False.

        Returns the source file name for this frame, or None if this frame
        shouldn't be measured.

        """
        return None

    def line_number_range(self, frame: FrameType) -> tuple[TLineNo, TLineNo]:
        """Get the range of source line numbers for a given a call frame.

        The call frame is examined, and the source line number in the original
        file is returned.  The return value is a pair of numbers, the starting
        line number and the ending line number, both inclusive.  For example,
        returning (5, 7) means that lines 5, 6, and 7 should be considered
        executed.

        This function might decide that the frame doesn't indicate any lines
        from the source file were executed.  Return (-1, -1) in this case to
        tell coverage.py that no lines should be recorded for this frame.

        """
        lineno = frame.f_lineno
        return lineno, lineno


@dataclasses.dataclass
class CodeRegion:
    """Data for a region of code found by :meth:`FileReporter.code_regions`."""

    #: The kind of region, like `"function"` or `"class"`. Must be one of the
    #: singular values returned by :meth:`FileReporter.code_region_kinds`.
    kind: str

    #: The name of the region. For example, a function or class name.
    name: str

    #: The line in the source file to link to when navigating to the region.
    #: Can be a line not mentioned in `lines`.
    start: int

    #: The lines in the region. Should be lines that could be executed in the
    #: region.  For example, a class region includes all of the lines in the
    #: methods of the class, but not the lines defining class attributes, since
    #: they are executed on import, not as part of exercising the class.  The
    #: set can include non-executable lines like blanks and comments.
    lines: set[int]

    def __lt__(self, other: CodeRegion) -> bool:
        """To support sorting to make test-writing easier."""
        if self.name == other.name:
            return min(self.lines) < min(other.lines)
        return self.name < other.name


@functools.total_ordering
class FileReporter(CoveragePluginBase):
    """Support needed for files during the analysis and reporting phases.

    File tracer plug-ins implement a subclass of `FileReporter`, and return
    instances from their :meth:`CoveragePlugin.file_reporter` method.

    There are many methods here, but only :meth:`lines` is required, to provide
    the set of executable lines in the file.

    See :ref:`howitworks` for details of the different coverage.py phases.

    """

    def __init__(self, filename: str) -> None:
        """Simple initialization of a `FileReporter`.

        The `filename` argument is the path to the file being reported.  This
        will be available as the `.filename` attribute on the object.  Other
        method implementations on this base class rely on this attribute.

        """
        self.filename = filename

    def __repr__(self) -> str:
        return f"<{self.__class__.__name__} filename={self.filename!r}>"

    def relative_filename(self) -> str:
        """Get the relative file name for this file.

        This file path will be displayed in reports.  The default
        implementation will supply the actual project-relative file path.  You
        only need to supply this method if you have an unusual syntax for file
        paths.

        """
        return files.relative_filename(self.filename)

    def source(self) -> str:
        """Get the source for the file.

        Returns a Unicode string.

        The base implementation simply reads the `self.filename` file and
        decodes it as UTF-8.  Override this method if your file isn't readable
        as a text file, or if you need other encoding support.

        """
        with open(self.filename, encoding="utf-8") as f:
            return f.read()

    def lines(self) -> set[TLineNo]:
        """Get the executable lines in this file.

        Your plug-in must determine which lines in the file were possibly
        executable.  This method returns a set of those line numbers.

        Returns a set of line numbers.

        """
        _needs_to_implement(self, "lines")

    def excluded_lines(self) -> set[TLineNo]:
        """Get the excluded executable lines in this file.

        Your plug-in can use any method it likes to allow the user to exclude
        executable lines from consideration.

        Returns a set of line numbers.

        The base implementation returns the empty set.

        """
        return set()

    def translate_lines(self, lines: Iterable[TLineNo]) -> set[TLineNo]:
        """Translate recorded lines into reported lines.

        Some file formats will want to report lines slightly differently than
        they are recorded.  For example, Python records the last line of a
        multi-line statement, but reports are nicer if they mention the first
        line.

        Your plug-in can optionally define this method to perform these kinds
        of adjustment.

        `lines` is a sequence of integers, the recorded line numbers.

        Returns a set of integers, the adjusted line numbers.

        The base implementation returns the numbers unchanged.

        """
        return set(lines)

    def arcs(self) -> set[TArc]:
        """Get the executable arcs in this file.

        To support branch coverage, your plug-in needs to be able to indicate
        possible execution paths, as a set of line number pairs.  Each pair is
        a `(prev, next)` pair indicating that execution can transition from the
        `prev` line number to the `next` line number.

        Returns a set of pairs of line numbers.  The default implementation
        returns an empty set.

        """
        return set()

    def no_branch_lines(self) -> set[TLineNo]:
        """Get the lines excused from branch coverage in this file.

        Your plug-in can use any method it likes to allow the user to exclude
        lines from consideration of branch coverage.

        Returns a set of line numbers.

        The base implementation returns the empty set.

        """
        return set()

    def translate_arcs(self, arcs: Iterable[TArc]) -> set[TArc]:
        """Translate recorded arcs into reported arcs.

        Similar to :meth:`translate_lines`, but for arcs.  `arcs` is a set of
        line number pairs.

        Returns a set of line number pairs.

        The default implementation returns `arcs` unchanged.

        """
        return set(arcs)

    def exit_counts(self) -> dict[TLineNo, int]:
        """Get a count of exits from that each line.

        To determine which lines are branches, coverage.py looks for lines that
        have more than one exit.  This function creates a dict mapping each
        executable line number to a count of how many exits it has.

        To be honest, this feels wrong, and should be refactored.  Let me know
        if you attempt to implement this method in your plug-in...

        """
        return {}

    def missing_arc_description(
        self,
        start: TLineNo,
        end: TLineNo,
        executed_arcs: Iterable[TArc] | None = None,     # pylint: disable=unused-argument
    ) -> str:
        """Provide an English sentence describing a missing arc.

        The `start` and `end` arguments are the line numbers of the missing
        arc. Negative numbers indicate entering or exiting code objects.

        The `executed_arcs` argument is a set of line number pairs, the arcs
        that were executed in this file.

        By default, this simply returns the string "Line {start} didn't jump
        to {end}".

        """
        return f"Line {start} didn't jump to line {end}"

    def source_token_lines(self) -> TSourceTokenLines:
        """Generate a series of tokenized lines, one for each line in `source`.

        These tokens are used for syntax-colored reports.

        Each line is a list of pairs, each pair is a token::

            [("key", "def"), ("ws", " "), ("nam", "hello"), ("op", "("), ... ]

        Each pair has a token class, and the token text.  The token classes
        are:

        * ``"com"``: a comment
        * ``"key"``: a keyword
        * ``"nam"``: a name, or identifier
        * ``"num"``: a number
        * ``"op"``: an operator
        * ``"str"``: a string literal
        * ``"ws"``: some white space
        * ``"txt"``: some other kind of text

        If you concatenate all the token texts, and then join them with
        newlines, you should have your original source back.

        The default implementation simply returns each line tagged as
        ``"txt"``.

        """
        for line in self.source().splitlines():
            yield [("txt", line)]

    def code_regions(self) -> Iterable[CodeRegion]:
        """Identify regions in the source file for finer reporting than by file.

        Returns an iterable of :class:`CodeRegion` objects.  The kinds reported
        should be in the possibilities returned by :meth:`code_region_kinds`.

        """
        return []

    def code_region_kinds(self) -> Iterable[tuple[str, str]]:
        """Return the kinds of code regions this plugin can find.

        The returned pairs are the singular and plural forms of the kinds::

            [
                ("function", "functions"),
                ("class", "classes"),
            ]

        This will usually be hard-coded, but could also differ by the specific
        source file involved.

        """
        return []

    def __eq__(self, other: Any) -> bool:
        return isinstance(other, FileReporter) and self.filename == other.filename

    def __lt__(self, other: Any) -> bool:
        return isinstance(other, FileReporter) and self.filename < other.filename

    # This object doesn't need to be hashed.
    __hash__ = None         # type: ignore[assignment]
