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

"""LCOV reporting for coverage.py."""

from __future__ import annotations

import base64
import hashlib
import sys

from typing import IO, Iterable, TYPE_CHECKING

from coverage.plugin import FileReporter
from coverage.report_core import get_analysis_to_report
from coverage.results import Analysis, Numbers
from coverage.types import TMorf

if TYPE_CHECKING:
    from coverage import Coverage


def line_hash(line: str) -> str:
    """Produce a hash of a source line for use in the LCOV file."""
    # The LCOV file format requires MD5 as a fingerprint of the file. This is
    # not a security use.  Some security scanners raise alarms about the use of
    # MD5 here, but it is a false positive. This is not a security concern.
    hashed = hashlib.md5(line.encode("utf-8")).digest()
    return base64.b64encode(hashed).decode("ascii").rstrip("=")


class LcovReporter:
    """A reporter for writing LCOV coverage reports."""

    report_type = "LCOV report"

    def __init__(self, coverage: Coverage) -> None:
        self.coverage = coverage
        self.total = Numbers(self.coverage.config.precision)

    def report(self, morfs: Iterable[TMorf] | None, outfile: IO[str]) -> float:
        """Renders the full lcov report.

        `morfs` is a list of modules or filenames

        outfile is the file object to write the file into.
        """

        self.coverage.get_data()
        outfile = outfile or sys.stdout

        for fr, analysis in get_analysis_to_report(self.coverage, morfs):
            self.get_lcov(fr, analysis, outfile)

        return self.total.n_statements and self.total.pc_covered

    def get_lcov(self, fr: FileReporter, analysis: Analysis, outfile: IO[str]) -> None:
        """Produces the lcov data for a single file.

        This currently supports both line and branch coverage,
        however function coverage is not supported.
        """
        self.total += analysis.numbers

        outfile.write("TN:\n")
        outfile.write(f"SF:{fr.relative_filename()}\n")
        source_lines = fr.source().splitlines()
        for covered in sorted(analysis.executed):
            if covered in analysis.excluded:
                # Do not report excluded as executed
                continue
            # Note: Coverage.py currently only supports checking *if* a line
            # has been executed, not how many times, so we set this to 1 for
            # nice output even if it's technically incorrect.

            # The lines below calculate a 64-bit encoded md5 hash of the line
            # corresponding to the DA lines in the lcov file, for either case
            # of the line being covered or missed in coverage.py. The final two
            # characters of the encoding ("==") are removed from the hash to
            # allow genhtml to run on the resulting lcov file.
            if source_lines:
                if covered-1 >= len(source_lines):
                    break
                line = source_lines[covered-1]
            else:
                line = ""
            outfile.write(f"DA:{covered},1,{line_hash(line)}\n")

        for missed in sorted(analysis.missing):
            # We don't have to skip excluded lines here, because `missing`
            # already doesn't have them.
            assert source_lines
            line = source_lines[missed-1]
            outfile.write(f"DA:{missed},0,{line_hash(line)}\n")

        outfile.write(f"LF:{analysis.numbers.n_statements}\n")
        outfile.write(f"LH:{analysis.numbers.n_executed}\n")

        # More information dense branch coverage data.
        missing_arcs = analysis.missing_branch_arcs()
        executed_arcs = analysis.executed_branch_arcs()
        for block_number, block_line_number in enumerate(
            sorted(analysis.branch_stats().keys()),
        ):
            for branch_number, line_number in enumerate(
                sorted(missing_arcs[block_line_number]),
            ):
                # The exit branches have a negative line number,
                # this will not produce valid lcov. Setting
                # the line number of the exit branch to 0 will allow
                # for valid lcov, while preserving the data.
                line_number = max(line_number, 0)
                outfile.write(f"BRDA:{line_number},{block_number},{branch_number},-\n")

            # The start value below allows for the block number to be
            # preserved between these two for loops (stopping the loop from
            # resetting the value of the block number to 0).
            for branch_number, line_number in enumerate(
                sorted(executed_arcs[block_line_number]),
                start=len(missing_arcs[block_line_number]),
            ):
                line_number = max(line_number, 0)
                outfile.write(f"BRDA:{line_number},{block_number},{branch_number},1\n")

        # Summary of the branch coverage.
        if analysis.has_arcs:
            branch_stats = analysis.branch_stats()
            brf = sum(t for t, k in branch_stats.values())
            brh = brf - sum(t - k for t, k in branch_stats.values())
            outfile.write(f"BRF:{brf}\n")
            outfile.write(f"BRH:{brh}\n")

        outfile.write("end_of_record\n")
