# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE

import collections
from typing import TYPE_CHECKING, Any, Callable, DefaultDict, Dict, List, Tuple

from pylint.exceptions import EmptyReportError
from pylint.interfaces import IChecker
from pylint.reporters.ureports.nodes import Section
from pylint.typing import CheckerStats

if TYPE_CHECKING:
    from pylint.lint.pylinter import PyLinter


class ReportsHandlerMixIn:
    """a mix-in class containing all the reports and stats manipulation
    related methods for the main lint class
    """

    def __init__(self) -> None:
        self._reports: DefaultDict[
            IChecker, List[Tuple[str, str, Callable]]
        ] = collections.defaultdict(list)
        self._reports_state: Dict[str, bool] = {}

    def report_order(self):
        """Return a list of reports, sorted in the order
        in which they must be called.
        """
        return list(self._reports)

    def register_report(
        self, reportid: str, r_title: str, r_cb: Callable, checker: IChecker
    ) -> None:
        """register a report

        reportid is the unique identifier for the report
        r_title the report's title
        r_cb the method to call to make the report
        checker is the checker defining the report
        """
        reportid = reportid.upper()
        self._reports[checker].append((reportid, r_title, r_cb))

    def enable_report(self, reportid: str) -> None:
        """disable the report of the given id"""
        reportid = reportid.upper()
        self._reports_state[reportid] = True

    def disable_report(self, reportid: str) -> None:
        """disable the report of the given id"""
        reportid = reportid.upper()
        self._reports_state[reportid] = False

    def report_is_enabled(self, reportid: str) -> bool:
        """return true if the report associated to the given identifier is
        enabled
        """
        return self._reports_state.get(reportid, True)

    def make_reports(  # type: ignore # ReportsHandlerMixIn is always mixed with PyLinter
        self: "PyLinter",
        stats: CheckerStats,
        old_stats: CheckerStats,
    ) -> Section:
        """render registered reports"""
        sect = Section("Report", f"{self.stats['statement']} statements analysed.")
        for checker in self.report_order():
            for reportid, r_title, r_cb in self._reports[checker]:
                if not self.report_is_enabled(reportid):
                    continue
                report_sect = Section(r_title)
                try:
                    r_cb(report_sect, stats, old_stats)
                except EmptyReportError:
                    continue
                report_sect.report_id = reportid
                sect.append(report_sect)
        return sect

    def add_stats(  # type: ignore # ReportsHandlerMixIn is always mixed with PyLinter
        self: "PyLinter", **kwargs: Any
    ) -> CheckerStats:
        """add some stats entries to the statistic dictionary
        raise an AssertionError if there is a key conflict
        """
        for key, value in kwargs.items():
            if key[-1] == "_":
                key = key[:-1]
            assert key not in self.stats
            self.stats[key] = value
        return self.stats
