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

"""Summary reporting"""

from __future__ import annotations

import sys
from collections.abc import Iterable
from typing import IO, TYPE_CHECKING, Any

from coverage.exceptions import ConfigError, NoDataError
from coverage.misc import human_sorted_items, plural
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


class SummaryReporter:
    """A reporter for writing the summary report."""

    def __init__(self, coverage: Coverage) -> None:
        self.coverage = coverage
        self.config = self.coverage.config
        self.branches = coverage.get_data().has_arcs()
        self.outfile: IO[str] | None = None
        self.output_format = self.config.format or "text"
        if self.output_format not in {"text", "markdown", "total"}:
            raise ConfigError(f"Unknown report format choice: {self.output_format!r}")
        self.fr_analyses: list[tuple[FileReporter, Analysis]] = []
        self.skipped_count = 0
        self.empty_count = 0
        self.total = Numbers(precision=self.config.precision)

    def write(self, line: str) -> None:
        """Write a line to the output, adding a newline."""
        assert self.outfile is not None
        self.outfile.write(line.rstrip())
        self.outfile.write("\n")

    def write_items(self, items: Iterable[str]) -> None:
        """Write a list of strings, joined together."""
        self.write("".join(items))

    def report_text(
        self,
        header: list[str],
        lines_values: list[list[Any]],
        total_line: list[Any],
        end_lines: list[str],
    ) -> None:
        """Internal method that prints report data in text format.

        `header` is a list with captions.
        `lines_values` is list of lists of sortable values.
        `total_line` is a list with values of the total line.
        `end_lines` is a list of ending lines with information about skipped files.

        """
        # Prepare the formatting strings, header, and column sorting.
        max_name = max([len(line[0]) for line in lines_values] + [5]) + 1
        max_n = max(len(total_line[header.index("Cover")]) + 2, len(" Cover")) + 1
        max_n = max([max_n] + [len(line[header.index("Cover")]) + 2 for line in lines_values])
        formats = dict(
            Name="{:{name_len}}",
            Stmts="{:>7}",
            Miss="{:>7}",
            Branch="{:>7}",
            BrPart="{:>7}",
            Cover="{:>{n}}",
            Missing="{:>10}",
        )
        header_items = [formats[item].format(item, name_len=max_name, n=max_n) for item in header]
        header_str = "".join(header_items)
        rule = "-" * len(header_str)

        # Write the header
        self.write(header_str)
        self.write(rule)

        # Write the data lines
        formats.update(
            dict(
                Cover="{:>{n}}%",
                Missing="   {:9}",
            )
        )
        for values in lines_values:
            self.write_items(
                (
                    formats[item].format(str(value), name_len=max_name, n=max_n - 1)
                    for item, value in zip(header, values)
                )
            )

        # Write a TOTAL line
        if lines_values:
            self.write(rule)

        self.write_items(
            (
                formats[item].format(str(value), name_len=max_name, n=max_n - 1)
                for item, value in zip(header, total_line)
            )
        )

        for end_line in end_lines:
            self.write(end_line)

    def report_markdown(
        self,
        header: list[str],
        lines_values: list[list[Any]],
        total_line: list[Any],
        end_lines: list[str],
    ) -> None:
        """Internal method that prints report data in markdown format.

        `header` is a list with captions.
        `lines_values` is a sorted list of lists containing coverage information.
        `total_line` is a list with values of the total line.
        `end_lines` is a list of ending lines with information about skipped files.

        """
        # Prepare the formatting strings, header, and column sorting.
        max_name = max((len(line[0].replace("_", "\\_")) for line in lines_values), default=0)
        max_name = max(max_name, len("**TOTAL**")) + 1
        formats = dict(
            Name="| {:{name_len}}|",
            Stmts="{:>9} |",
            Miss="{:>9} |",
            Branch="{:>9} |",
            BrPart="{:>9} |",
            Cover="{:>{n}} |",
            Missing="{:>10} |",
        )
        max_n = max(len(total_line[header.index("Cover")]) + 6, len(" Cover "))
        header_items = [formats[item].format(item, name_len=max_name, n=max_n) for item in header]
        header_str = "".join(header_items)
        rule_str = "|" + " ".join(
            ["- |".rjust(len(header_items[0]) - 1, "-")]
            + ["-: |".rjust(len(item) - 1, "-") for item in header_items[1:]],
        )

        # Write the header
        self.write(header_str)
        self.write(rule_str)

        # Write the data lines
        for values in lines_values:
            formats.update(
                dict(
                    Cover="{:>{n}}% |",
                )
            )
            self.write_items(
                (
                    formats[item].format(
                        str(value).replace("_", "\\_"), name_len=max_name, n=max_n - 1
                    )
                    for item, value in zip(header, values)
                )
            )

        # Write the TOTAL line
        formats.update(
            dict(
                Name="|{:>{name_len}} |",
                Cover="{:>{n}} |",
            ),
        )
        total_line_items: list[str] = []
        for item, value in zip(header, total_line):
            if value == "":
                insert = value
            elif item == "Cover":
                insert = f" **{value}%**"
            else:
                insert = f" **{value}**"
            total_line_items += formats[item].format(insert, name_len=max_name, n=max_n)
        self.write_items(total_line_items)

        for end_line in end_lines:
            self.write(end_line)

    def report(self, morfs: Iterable[TMorf] | None, outfile: IO[str] | None = None) -> float:
        """Writes a report summarizing coverage statistics per module.

        `outfile` is a text-mode file object to write the summary to.

        """
        self.outfile = outfile or sys.stdout

        self.coverage.get_data().set_query_contexts(self.config.report_contexts)
        for fr, analysis in get_analysis_to_report(self.coverage, morfs):
            self.report_one_file(fr, analysis)

        if not self.total.n_files and not self.skipped_count:
            raise NoDataError("No data to report.")

        if self.output_format == "total":
            self.write(self.total.pc_covered_str)
        else:
            self.tabular_report()

        return self.total.pc_covered

    def tabular_report(self) -> None:
        """Writes tabular report formats."""
        # Prepare the header line and column sorting.
        header = ["Name", "Stmts", "Miss"]
        if self.branches:
            header += ["Branch", "BrPart"]
        header += ["Cover"]
        if self.config.show_missing:
            header += ["Missing"]

        column_order = dict(name=0, stmts=1, miss=2, cover=-1)
        if self.branches:
            column_order.update(dict(branch=3, brpart=4))

        # `lines_values` is list of lists of sortable values.
        lines_values = []

        for fr, analysis in self.fr_analyses:
            nums = analysis.numbers
            args = [fr.relative_filename(), nums.n_statements, nums.n_missing]
            if self.branches:
                args += [nums.n_branches, nums.n_partial_branches]
            args += [nums.pc_covered_str]
            if self.config.show_missing:
                args += [analysis.missing_formatted(branches=True)]
            args += [nums.pc_covered]
            lines_values.append(args)

        # Line sorting.
        sort_option = (self.config.sort or "name").lower()
        reverse = False
        if sort_option[0] == "-":
            reverse = True
            sort_option = sort_option[1:]
        elif sort_option[0] == "+":
            sort_option = sort_option[1:]
        sort_idx = column_order.get(sort_option)
        if sort_idx is None:
            raise ConfigError(f"Invalid sorting option: {self.config.sort!r}")
        if sort_option == "name":
            lines_values = human_sorted_items(lines_values, reverse=reverse)
        else:
            lines_values.sort(
                key=lambda line: (line[sort_idx], line[0]),
                reverse=reverse,
            )

        # Calculate total if we had at least one file.
        total_line = ["TOTAL", self.total.n_statements, self.total.n_missing]
        if self.branches:
            total_line += [self.total.n_branches, self.total.n_partial_branches]
        total_line += [self.total.pc_covered_str]
        if self.config.show_missing:
            total_line += [""]

        # Create other final lines.
        end_lines = []
        if self.config.skip_covered and self.skipped_count:
            files = plural(self.skipped_count, "file")
            end_lines.append(
                f"\n{self.skipped_count} {files} skipped due to complete coverage.",
            )
        if self.config.skip_empty and self.empty_count:
            files = plural(self.empty_count, "file")
            end_lines.append(f"\n{self.empty_count} empty {files} skipped.")

        if self.output_format == "markdown":
            formatter = self.report_markdown
        else:
            formatter = self.report_text
        formatter(header, lines_values, total_line, end_lines)

    def report_one_file(self, fr: FileReporter, analysis: Analysis) -> None:
        """Report on just one file, the callback from report()."""
        nums = analysis.numbers
        self.total += nums

        no_missing_lines = (nums.n_missing == 0)  # fmt: skip
        no_missing_branches = (nums.n_partial_branches == 0)  # fmt: skip
        if self.config.skip_covered and no_missing_lines and no_missing_branches:
            # Don't report on 100% files.
            self.skipped_count += 1
        elif self.config.skip_empty and nums.n_statements == 0:
            # Don't report on empty files.
            self.empty_count += 1
        else:
            self.fr_analyses.append((fr, analysis))
