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

"""Python source expertise for coverage.py"""

from __future__ import annotations

import os.path
import types
import zipimport

from typing import Iterable, TYPE_CHECKING

from coverage import env
from coverage.exceptions import CoverageException, NoSource
from coverage.files import canonical_filename, relative_filename, zip_location
from coverage.misc import isolate_module, join_regex
from coverage.parser import PythonParser
from coverage.phystokens import source_token_lines, source_encoding
from coverage.plugin import CodeRegion, FileReporter
from coverage.regions import code_regions
from coverage.types import TArc, TLineNo, TMorf, TSourceTokenLines

if TYPE_CHECKING:
    from coverage import Coverage

os = isolate_module(os)


def read_python_source(filename: str) -> bytes:
    """Read the Python source text from `filename`.

    Returns bytes.

    """
    with open(filename, "rb") as f:
        source = f.read()

    return source.replace(b"\r\n", b"\n").replace(b"\r", b"\n")


def get_python_source(filename: str) -> str:
    """Return the source code, as unicode."""
    base, ext = os.path.splitext(filename)
    if ext == ".py" and env.WINDOWS:
        exts = [".py", ".pyw"]
    else:
        exts = [ext]

    source_bytes: bytes | None
    for ext in exts:
        try_filename = base + ext
        if os.path.exists(try_filename):
            # A regular text file: open it.
            source_bytes = read_python_source(try_filename)
            break

        # Maybe it's in a zip file?
        source_bytes = get_zip_bytes(try_filename)
        if source_bytes is not None:
            break
    else:
        # Couldn't find source.
        raise NoSource(f"No source for code: '{filename}'.")

    # Replace \f because of http://bugs.python.org/issue19035
    source_bytes = source_bytes.replace(b"\f", b" ")
    source = source_bytes.decode(source_encoding(source_bytes), "replace")

    # Python code should always end with a line with a newline.
    if source and source[-1] != "\n":
        source += "\n"

    return source


def get_zip_bytes(filename: str) -> bytes | None:
    """Get data from `filename` if it is a zip file path.

    Returns the bytestring data read from the zip file, or None if no zip file
    could be found or `filename` isn't in it.  The data returned will be
    an empty string if the file is empty.

    """
    zipfile_inner = zip_location(filename)
    if zipfile_inner is not None:
        zipfile, inner = zipfile_inner
        try:
            zi = zipimport.zipimporter(zipfile)
        except zipimport.ZipImportError:
            return None
        try:
            data = zi.get_data(inner)
        except OSError:
            return None
        return data
    return None


def source_for_file(filename: str) -> str:
    """Return the source filename for `filename`.

    Given a file name being traced, return the best guess as to the source
    file to attribute it to.

    """
    if filename.endswith(".py"):
        # .py files are themselves source files.
        return filename

    elif filename.endswith((".pyc", ".pyo")):
        # Bytecode files probably have source files near them.
        py_filename = filename[:-1]
        if os.path.exists(py_filename):
            # Found a .py file, use that.
            return py_filename
        if env.WINDOWS:
            # On Windows, it could be a .pyw file.
            pyw_filename = py_filename + "w"
            if os.path.exists(pyw_filename):
                return pyw_filename
        # Didn't find source, but it's probably the .py file we want.
        return py_filename

    # No idea, just use the file name as-is.
    return filename


def source_for_morf(morf: TMorf) -> str:
    """Get the source filename for the module-or-file `morf`."""
    if hasattr(morf, "__file__") and morf.__file__:
        filename = morf.__file__
    elif isinstance(morf, types.ModuleType):
        # A module should have had .__file__, otherwise we can't use it.
        # This could be a PEP-420 namespace package.
        raise CoverageException(f"Module {morf} has no file")
    else:
        filename = morf

    filename = source_for_file(filename)
    return filename


class PythonFileReporter(FileReporter):
    """Report support for a Python file."""

    def __init__(self, morf: TMorf, coverage: Coverage | None = None) -> None:
        self.coverage = coverage

        filename = source_for_morf(morf)

        fname = filename
        canonicalize = True
        if self.coverage is not None:
            if self.coverage.config.relative_files:
                canonicalize = False
        if canonicalize:
            fname = canonical_filename(filename)
        super().__init__(fname)

        if hasattr(morf, "__name__"):
            name = morf.__name__.replace(".", os.sep)
            if os.path.basename(filename).startswith("__init__."):
                name += os.sep + "__init__"
            name += ".py"
        else:
            name = relative_filename(filename)
        self.relname = name

        self._source: str | None = None
        self._parser: PythonParser | None = None
        self._excluded = None

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

    def relative_filename(self) -> str:
        return self.relname

    @property
    def parser(self) -> PythonParser:
        """Lazily create a :class:`PythonParser`."""
        assert self.coverage is not None
        if self._parser is None:
            self._parser = PythonParser(
                filename=self.filename,
                exclude=self.coverage._exclude_regex("exclude"),
            )
            self._parser.parse_source()
        return self._parser

    def lines(self) -> set[TLineNo]:
        """Return the line numbers of statements in the file."""
        return self.parser.statements

    def excluded_lines(self) -> set[TLineNo]:
        """Return the line numbers of statements in the file."""
        return self.parser.excluded

    def translate_lines(self, lines: Iterable[TLineNo]) -> set[TLineNo]:
        return self.parser.translate_lines(lines)

    def translate_arcs(self, arcs: Iterable[TArc]) -> set[TArc]:
        return self.parser.translate_arcs(arcs)

    def no_branch_lines(self) -> set[TLineNo]:
        assert self.coverage is not None
        no_branch = self.parser.lines_matching(
            join_regex(
                self.coverage.config.partial_list
                + self.coverage.config.partial_always_list
            )
        )
        return no_branch

    def arcs(self) -> set[TArc]:
        return self.parser.arcs()

    def exit_counts(self) -> dict[TLineNo, int]:
        return self.parser.exit_counts()

    def missing_arc_description(
        self,
        start: TLineNo,
        end: TLineNo,
        executed_arcs: Iterable[TArc] | None = None,
    ) -> str:
        return self.parser.missing_arc_description(start, end, executed_arcs)

    def source(self) -> str:
        if self._source is None:
            self._source = get_python_source(self.filename)
        return self._source

    def should_be_python(self) -> bool:
        """Does it seem like this file should contain Python?

        This is used to decide if a file reported as part of the execution of
        a program was really likely to have contained Python in the first
        place.

        """
        # Get the file extension.
        _, ext = os.path.splitext(self.filename)

        # Anything named *.py* should be Python.
        if ext.startswith(".py"):
            return True
        # A file with no extension should be Python.
        if not ext:
            return True
        # Everything else is probably not Python.
        return False

    def source_token_lines(self) -> TSourceTokenLines:
        return source_token_lines(self.source())

    def code_regions(self) -> Iterable[CodeRegion]:
        return code_regions(self.source())

    def code_region_kinds(self) -> Iterable[tuple[str, str]]:
        return [
            ("function", "functions"),
            ("class", "classes"),
        ]
