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

"""HTML reporting for coverage.py."""

from __future__ import annotations

import collections
import dataclasses
import datetime
import functools
import json
import os
import re
import string

from dataclasses import dataclass, field
from typing import Any, Iterable, TYPE_CHECKING

import coverage
from coverage.data import CoverageData, add_data_to_hash
from coverage.exceptions import NoDataError
from coverage.files import flat_rootname
from coverage.misc import (
    ensure_dir, file_be_gone, Hasher, isolate_module, format_local_datetime,
    human_sorted, plural, stdout_link,
)
from coverage.report_core import get_analysis_to_report
from coverage.results import Analysis, Numbers
from coverage.templite import Templite
from coverage.types import TLineNo, TMorf
from coverage.version import __url__


if TYPE_CHECKING:
    from coverage import Coverage
    from coverage.plugins import FileReporter


os = isolate_module(os)


def data_filename(fname: str) -> str:
    """Return the path to an "htmlfiles" data file of ours.
    """
    static_dir = os.path.join(os.path.dirname(__file__), "htmlfiles")
    static_filename = os.path.join(static_dir, fname)
    return static_filename


def read_data(fname: str) -> str:
    """Return the contents of a data file of ours."""
    with open(data_filename(fname)) as data_file:
        return data_file.read()


def write_html(fname: str, html: str) -> None:
    """Write `html` to `fname`, properly encoded."""
    html = re.sub(r"(\A\s+)|(\s+$)", "", html, flags=re.MULTILINE) + "\n"
    with open(fname, "wb") as fout:
        fout.write(html.encode("ascii", "xmlcharrefreplace"))


@dataclass
class LineData:
    """The data for each source line of HTML output."""
    tokens: list[tuple[str, str]]
    number: TLineNo
    category: str
    contexts: list[str]
    contexts_label: str
    context_list: list[str]
    short_annotations: list[str]
    long_annotations: list[str]
    html: str = ""
    context_str: str | None = None
    annotate: str | None = None
    annotate_long: str | None = None
    css_class: str = ""


@dataclass
class FileData:
    """The data for each source file of HTML output."""
    relative_filename: str
    nums: Numbers
    lines: list[LineData]


@dataclass
class IndexItem:
    """Information for each index entry, to render an index page."""
    url: str = ""
    file: str = ""
    description: str = ""
    nums: Numbers = field(default_factory=Numbers)


@dataclass
class IndexPage:
    """Data for each index page."""
    noun: str
    plural: str
    filename: str
    summaries: list[IndexItem]
    totals: Numbers
    skipped_covered_count: int
    skipped_empty_count: int


class HtmlDataGeneration:
    """Generate structured data to be turned into HTML reports."""

    EMPTY = "(empty)"

    def __init__(self, cov: Coverage) -> None:
        self.coverage = cov
        self.config = self.coverage.config
        self.data = self.coverage.get_data()
        self.has_arcs = self.data.has_arcs()
        if self.config.show_contexts:
            if self.data.measured_contexts() == {""}:
                self.coverage._warn("No contexts were measured")
        self.data.set_query_contexts(self.config.report_contexts)

    def data_for_file(self, fr: FileReporter, analysis: Analysis) -> FileData:
        """Produce the data needed for one file's report."""
        if self.has_arcs:
            missing_branch_arcs = analysis.missing_branch_arcs()
            arcs_executed = analysis.arcs_executed
        else:
            missing_branch_arcs = {}
            arcs_executed = []

        if self.config.show_contexts:
            contexts_by_lineno = self.data.contexts_by_lineno(analysis.filename)

        lines = []

        for lineno, tokens in enumerate(fr.source_token_lines(), start=1):
            # Figure out how to mark this line.
            category = ""
            short_annotations = []
            long_annotations = []

            if lineno in analysis.excluded:
                category = "exc"
            elif lineno in analysis.missing:
                category = "mis"
            elif self.has_arcs and lineno in missing_branch_arcs:
                category = "par"
                for b in missing_branch_arcs[lineno]:
                    if b < 0:
                        short_annotations.append("exit")
                    else:
                        short_annotations.append(str(b))
                    long_annotations.append(fr.missing_arc_description(lineno, b, arcs_executed))
            elif lineno in analysis.statements:
                category = "run"

            contexts = []
            contexts_label = ""
            context_list = []
            if category and self.config.show_contexts:
                contexts = human_sorted(c or self.EMPTY for c in contexts_by_lineno.get(lineno, ()))
                if contexts == [self.EMPTY]:
                    contexts_label = self.EMPTY
                else:
                    contexts_label = f"{len(contexts)} ctx"
                    context_list = contexts

            lines.append(LineData(
                tokens=tokens,
                number=lineno,
                category=category,
                contexts=contexts,
                contexts_label=contexts_label,
                context_list=context_list,
                short_annotations=short_annotations,
                long_annotations=long_annotations,
            ))

        file_data = FileData(
            relative_filename=fr.relative_filename(),
            nums=analysis.numbers,
            lines=lines,
        )

        return file_data


class FileToReport:
    """A file we're considering reporting."""
    def __init__(self, fr: FileReporter, analysis: Analysis) -> None:
        self.fr = fr
        self.analysis = analysis
        self.rootname = flat_rootname(fr.relative_filename())
        self.html_filename = self.rootname + ".html"
        self.prev_html = self.next_html = ""


HTML_SAFE = string.ascii_letters + string.digits + "!#$%'()*+,-./:;=?@[]^_`{|}~"

@functools.lru_cache(maxsize=None)
def encode_int(n: int) -> str:
    """Create a short HTML-safe string from an integer, using HTML_SAFE."""
    if n == 0:
        return HTML_SAFE[0]

    r = []
    while n:
        n, t = divmod(n, len(HTML_SAFE))
        r.append(HTML_SAFE[t])
    return "".join(r)


def copy_with_cache_bust(src: str, dest_dir: str) -> str:
    """Copy `src` to `dest_dir`, adding a hash to the name.

    Returns the updated destination file name with hash.
    """
    with open(src, "rb") as f:
        text = f.read()
    h = Hasher()
    h.update(text)
    cache_bust = h.hexdigest()[:8]
    src_base = os.path.basename(src)
    dest = src_base.replace(".", f"_cb_{cache_bust}.")
    with open(os.path.join(dest_dir, dest), "wb") as f:
        f.write(text)
    return dest


class HtmlReporter:
    """HTML reporting."""

    # These files will be copied from the htmlfiles directory to the output
    # directory.
    STATIC_FILES = [
        "style.css",
        "coverage_html.js",
        "keybd_closed.png",
        "favicon_32.png",
    ]

    def __init__(self, cov: Coverage) -> None:
        self.coverage = cov
        self.config = self.coverage.config
        self.directory = self.config.html_dir

        self.skip_covered = self.config.html_skip_covered
        if self.skip_covered is None:
            self.skip_covered = self.config.skip_covered
        self.skip_empty = self.config.html_skip_empty
        if self.skip_empty is None:
            self.skip_empty = self.config.skip_empty

        title = self.config.html_title

        self.extra_css = bool(self.config.extra_css)

        self.data = self.coverage.get_data()
        self.has_arcs = self.data.has_arcs()

        self.index_pages: dict[str, IndexPage] = {
            "file": self.new_index_page("file", "files"),
        }
        self.incr = IncrementalChecker(self.directory)
        self.datagen = HtmlDataGeneration(self.coverage)
        self.directory_was_empty = False
        self.first_fr = None
        self.final_fr = None

        self.template_globals = {
            # Functions available in the templates.
            "escape": escape,
            "pair": pair,
            "len": len,

            # Constants for this report.
            "__url__": __url__,
            "__version__": coverage.__version__,
            "title": title,
            "time_stamp": format_local_datetime(datetime.datetime.now()),
            "extra_css": self.extra_css,
            "has_arcs": self.has_arcs,
            "show_contexts": self.config.show_contexts,
            "statics": {},

            # Constants for all reports.
            # These css classes determine which lines are highlighted by default.
            "category": {
                "exc": "exc show_exc",
                "mis": "mis show_mis",
                "par": "par run show_par",
                "run": "run",
            },
        }
        self.index_tmpl = Templite(read_data("index.html"), self.template_globals)
        self.pyfile_html_source = read_data("pyfile.html")
        self.source_tmpl = Templite(self.pyfile_html_source, self.template_globals)

    def new_index_page(self, noun: str, plural_noun: str) -> IndexPage:
        """Create an IndexPage for a kind of region."""
        return IndexPage(
            noun=noun,
            plural=plural_noun,
            filename="index.html" if noun == "file" else f"{noun}_index.html",
            summaries=[],
            totals=Numbers(precision=self.config.precision),
            skipped_covered_count=0,
            skipped_empty_count=0,
        )

    def report(self, morfs: Iterable[TMorf] | None) -> float:
        """Generate an HTML report for `morfs`.

        `morfs` is a list of modules or file names.

        """
        # Read the status data and check that this run used the same
        # global data as the last run.
        self.incr.read()
        self.incr.check_global_data(self.config, self.pyfile_html_source)

        # Process all the files. For each page we need to supply a link
        # to the next and previous page.
        files_to_report = []

        have_data = False
        for fr, analysis in get_analysis_to_report(self.coverage, morfs):
            have_data = True
            ftr = FileToReport(fr, analysis)
            if self.should_report(analysis, self.index_pages["file"]):
                files_to_report.append(ftr)
            else:
                file_be_gone(os.path.join(self.directory, ftr.html_filename))

        if not have_data:
            raise NoDataError("No data to report.")

        self.make_directory()
        self.make_local_static_report_files()

        if files_to_report:
            for ftr1, ftr2 in zip(files_to_report[:-1], files_to_report[1:]):
                ftr1.next_html = ftr2.html_filename
                ftr2.prev_html = ftr1.html_filename
            files_to_report[0].prev_html = "index.html"
            files_to_report[-1].next_html = "index.html"

        for ftr in files_to_report:
            self.write_html_page(ftr)
            for noun, plural_noun in ftr.fr.code_region_kinds():
                if noun not in self.index_pages:
                    self.index_pages[noun] = self.new_index_page(noun, plural_noun)

        # Write the index page.
        if files_to_report:
            first_html = files_to_report[0].html_filename
            final_html = files_to_report[-1].html_filename
        else:
            first_html = final_html = "index.html"
        self.write_file_index_page(first_html, final_html)

        # Write function and class index pages.
        self.write_region_index_pages(files_to_report)

        return (
            self.index_pages["file"].totals.n_statements
            and self.index_pages["file"].totals.pc_covered
        )

    def make_directory(self) -> None:
        """Make sure our htmlcov directory exists."""
        ensure_dir(self.directory)
        if not os.listdir(self.directory):
            self.directory_was_empty = True

    def copy_static_file(self, src: str, slug: str = "") -> None:
        """Copy a static file into the output directory with cache busting."""
        dest = copy_with_cache_bust(src, self.directory)
        if not slug:
            slug = os.path.basename(src).replace(".", "_")
        self.template_globals["statics"][slug] = dest # type: ignore

    def make_local_static_report_files(self) -> None:
        """Make local instances of static files for HTML report."""

        # The files we provide must always be copied.
        for static in self.STATIC_FILES:
            self.copy_static_file(data_filename(static))

        # The user may have extra CSS they want copied.
        if self.extra_css:
            assert self.config.extra_css is not None
            self.copy_static_file(self.config.extra_css, slug="extra_css")

        # Only write the .gitignore file if the directory was originally empty.
        # .gitignore can't be copied from the source tree because if it was in
        # the source tree, it would stop the static files from being checked in.
        if self.directory_was_empty:
            with open(os.path.join(self.directory, ".gitignore"), "w") as fgi:
                fgi.write("# Created by coverage.py\n*\n")

    def should_report(self, analysis: Analysis, index_page: IndexPage) -> bool:
        """Determine if we'll report this file or region."""
        # Get the numbers for this file.
        nums = analysis.numbers
        index_page.totals += nums

        if self.skip_covered:
            # Don't report on 100% files.
            no_missing_lines = (nums.n_missing == 0)
            no_missing_branches = (nums.n_partial_branches == 0)
            if no_missing_lines and no_missing_branches:
                index_page.skipped_covered_count += 1
                return False

        if self.skip_empty:
            # Don't report on empty files.
            if nums.n_statements == 0:
                index_page.skipped_empty_count += 1
                return False

        return True

    def write_html_page(self, ftr: FileToReport) -> None:
        """Generate an HTML page for one source file.

        If the page on disk is already correct based on our incremental status
        checking, then the page doesn't have to be generated, and this function
        only does page summary bookkeeping.

        """
        # Find out if the page on disk is already correct.
        if self.incr.can_skip_file(self.data, ftr.fr, ftr.rootname):
            self.index_pages["file"].summaries.append(self.incr.index_info(ftr.rootname))
            return

        # Write the HTML page for this source file.
        file_data = self.datagen.data_for_file(ftr.fr, ftr.analysis)

        contexts = collections.Counter(c for cline in file_data.lines for c in cline.contexts)
        context_codes = {y: i for (i, y) in enumerate(x[0] for x in contexts.most_common())}
        if context_codes:
            contexts_json = json.dumps(
                {encode_int(v): k for (k, v) in context_codes.items()},
                indent=2,
            )
        else:
            contexts_json = None

        for ldata in file_data.lines:
            # Build the HTML for the line.
            html_parts = []
            for tok_type, tok_text in ldata.tokens:
                if tok_type == "ws":
                    html_parts.append(escape(tok_text))
                else:
                    tok_html = escape(tok_text) or "&nbsp;"
                    html_parts.append(f'<span class="{tok_type}">{tok_html}</span>')
            ldata.html = "".join(html_parts)
            if ldata.context_list:
                encoded_contexts = [
                    encode_int(context_codes[c_context]) for c_context in ldata.context_list
                ]
                code_width = max(len(ec) for ec in encoded_contexts)
                ldata.context_str = (
                    str(code_width)
                    + "".join(ec.ljust(code_width) for ec in encoded_contexts)
                )
            else:
                ldata.context_str = ""

            if ldata.short_annotations:
                # 202F is NARROW NO-BREAK SPACE.
                # 219B is RIGHTWARDS ARROW WITH STROKE.
                ldata.annotate = ",&nbsp;&nbsp; ".join(
                    f"{ldata.number}&#x202F;&#x219B;&#x202F;{d}"
                    for d in ldata.short_annotations
                )
            else:
                ldata.annotate = None

            if ldata.long_annotations:
                longs = ldata.long_annotations
                if len(longs) == 1:
                    ldata.annotate_long = longs[0]
                else:
                    ldata.annotate_long = "{:d} missed branches: {}".format(
                        len(longs),
                        ", ".join(
                            f"{num:d}) {ann_long}"
                            for num, ann_long in enumerate(longs, start=1)
                        ),
                    )
            else:
                ldata.annotate_long = None

            css_classes = []
            if ldata.category:
                css_classes.append(
                    self.template_globals["category"][ldata.category],   # type: ignore[index]
                )
            ldata.css_class = " ".join(css_classes) or "pln"

        html_path = os.path.join(self.directory, ftr.html_filename)
        html = self.source_tmpl.render({
            **file_data.__dict__,
            "contexts_json": contexts_json,
            "prev_html": ftr.prev_html,
            "next_html": ftr.next_html,
        })
        write_html(html_path, html)

        # Save this file's information for the index page.
        index_info = IndexItem(
            url = ftr.html_filename,
            file = escape(ftr.fr.relative_filename()),
            nums = ftr.analysis.numbers,
        )
        self.index_pages["file"].summaries.append(index_info)
        self.incr.set_index_info(ftr.rootname, index_info)

    def write_file_index_page(self, first_html: str, final_html: str) -> None:
        """Write the file index page for this report."""
        index_file = self.write_index_page(
            self.index_pages["file"],
            first_html=first_html,
            final_html=final_html,
        )

        print_href = stdout_link(index_file, f"file://{os.path.abspath(index_file)}")
        self.coverage._message(f"Wrote HTML report to {print_href}")

        # Write the latest hashes for next time.
        self.incr.write()

    def write_region_index_pages(self, files_to_report: Iterable[FileToReport]) -> None:
        """Write the other index pages for this report."""
        for ftr in files_to_report:
            region_nouns = [pair[0] for pair in ftr.fr.code_region_kinds()]
            num_lines = len(ftr.fr.source().splitlines())
            regions = ftr.fr.code_regions()

            for noun in region_nouns:
                page_data = self.index_pages[noun]
                outside_lines = set(range(1, num_lines + 1))

                for region in regions:
                    if region.kind != noun:
                        continue
                    outside_lines -= region.lines
                    analysis = ftr.analysis.narrow(region.lines)
                    if not self.should_report(analysis, page_data):
                        continue
                    sorting_name = region.name.rpartition(".")[-1].lstrip("_")
                    page_data.summaries.append(IndexItem(
                        url=f"{ftr.html_filename}#t{region.start}",
                        file=escape(ftr.fr.relative_filename()),
                        description=(
                            f"<data value='{escape(sorting_name)}'>"
                            + escape(region.name)
                            + "</data>"
                        ),
                        nums=analysis.numbers,
                    ))

                analysis = ftr.analysis.narrow(outside_lines)
                if self.should_report(analysis, page_data):
                    page_data.summaries.append(IndexItem(
                        url=ftr.html_filename,
                        file=escape(ftr.fr.relative_filename()),
                        description=(
                            "<data value=''>"
                            + f"<span class='no-noun'>(no {escape(noun)})</span>"
                            + "</data>"
                        ),
                        nums=analysis.numbers,
                    ))

        for noun, index_page in self.index_pages.items():
            if noun != "file":
                self.write_index_page(index_page)

    def write_index_page(self, index_page: IndexPage, **kwargs: str) -> str:
        """Write an index page specified by `index_page`.

        Returns the filename created.
        """
        skipped_covered_msg = skipped_empty_msg = ""
        if n := index_page.skipped_covered_count:
            word = plural(n, index_page.noun, index_page.plural)
            skipped_covered_msg = f"{n} {word} skipped due to complete coverage."
        if n := index_page.skipped_empty_count:
            word = plural(n, index_page.noun, index_page.plural)
            skipped_empty_msg = f"{n} empty {word} skipped."

        index_buttons = [
            {
                "label": ip.plural.title(),
                "url": ip.filename if ip.noun != index_page.noun else "",
                "current": ip.noun == index_page.noun,
            }
            for ip in self.index_pages.values()
        ]
        render_data = {
            "regions": index_page.summaries,
            "totals": index_page.totals,
            "noun": index_page.noun,
            "region_noun": index_page.noun if index_page.noun != "file" else "",
            "skip_covered": self.skip_covered,
            "skipped_covered_msg": skipped_covered_msg,
            "skipped_empty_msg": skipped_empty_msg,
            "first_html": "",
            "final_html": "",
            "index_buttons": index_buttons,
        }
        render_data.update(kwargs)
        html = self.index_tmpl.render(render_data)

        index_file = os.path.join(self.directory, index_page.filename)
        write_html(index_file, html)
        return index_file


@dataclass
class FileInfo:
    """Summary of the information from last rendering, to avoid duplicate work."""
    hash: str = ""
    index: IndexItem = field(default_factory=IndexItem)


class IncrementalChecker:
    """Logic and data to support incremental reporting.

    When generating an HTML report, often only a few of the source files have
    changed since the last time we made the HTML report.  This means previously
    created HTML pages can be reused without generating them again, speeding
    the command.

    This class manages a JSON data file that captures enough information to
    know whether an HTML page for a .py file needs to be regenerated or not.
    The data file also needs to store all the information needed to create the
    entry for the file on the index page so that if the HTML page is reused,
    the index page can still be created to refer to it.

    The data looks like::

        {
            "note": "This file is an internal implementation detail ...",
            // A fixed number indicating the data format.  STATUS_FORMAT
            "format": 5,
            // The version of coverage.py
            "version": "7.4.4",
            // A hash of a number of global things, including the configuration
            // settings and the pyfile.html template itself.
            "globals": "540ee119c15d52a68a53fe6f0897346d",
            "files": {
                // An entry for each source file keyed by the flat_rootname().
                "z_7b071bdc2a35fa80___init___py": {
                    // Hash of the source, the text of the .py file.
                    "hash": "e45581a5b48f879f301c0f30bf77a50c",
                    // Information for the index.html file.
                    "index": {
                        "url": "z_7b071bdc2a35fa80___init___py.html",
                        "file": "cogapp/__init__.py",
                        "description": "",
                        // The Numbers for this file.
                        "nums": { "precision": 2, "n_files": 1, "n_statements": 43, ... }
                    }
                },
                ...
            }
        }

    """

    STATUS_FILE = "status.json"
    STATUS_FORMAT = 5
    NOTE = (
        "This file is an internal implementation detail to speed up HTML report"
        + " generation. Its format can change at any time. You might be looking"
        + " for the JSON report: https://coverage.rtfd.io/cmd.html#cmd-json"
    )

    def __init__(self, directory: str) -> None:
        self.directory = directory
        self._reset()

    def _reset(self) -> None:
        """Initialize to empty. Causes all files to be reported."""
        self.globals = ""
        self.files: dict[str, FileInfo] = {}

    def read(self) -> None:
        """Read the information we stored last time."""
        try:
            status_file = os.path.join(self.directory, self.STATUS_FILE)
            with open(status_file) as fstatus:
                status = json.load(fstatus)
        except (OSError, ValueError):
            # Status file is missing or malformed.
            usable = False
        else:
            if status["format"] != self.STATUS_FORMAT:
                usable = False
            elif status["version"] != coverage.__version__:
                usable = False
            else:
                usable = True

        if usable:
            self.files = {}
            for filename, filedict in status["files"].items():
                indexdict = filedict["index"]
                index_item = IndexItem(**indexdict)
                index_item.nums = Numbers(**indexdict["nums"])
                fileinfo = FileInfo(
                    hash=filedict["hash"],
                    index=index_item,
                )
                self.files[filename] = fileinfo
            self.globals = status["globals"]
        else:
            self._reset()

    def write(self) -> None:
        """Write the current status."""
        status_file = os.path.join(self.directory, self.STATUS_FILE)
        status_data = {
            "note": self.NOTE,
            "format": self.STATUS_FORMAT,
            "version": coverage.__version__,
            "globals": self.globals,
            "files": {
                fname: dataclasses.asdict(finfo)
                for fname, finfo in self.files.items()
            },
        }
        with open(status_file, "w") as fout:
            json.dump(status_data, fout, separators=(",", ":"))

    def check_global_data(self, *data: Any) -> None:
        """Check the global data that can affect incremental reporting.

        Pass in whatever global information could affect the content of the
        HTML pages.  If the global data has changed since last time, this will
        clear the data so that all files are regenerated.

        """
        m = Hasher()
        for d in data:
            m.update(d)
        these_globals = m.hexdigest()
        if self.globals != these_globals:
            self._reset()
            self.globals = these_globals

    def can_skip_file(self, data: CoverageData, fr: FileReporter, rootname: str) -> bool:
        """Can we skip reporting this file?

        `data` is a CoverageData object, `fr` is a `FileReporter`, and
        `rootname` is the name being used for the file.

        Returns True if the HTML page is fine as-is, False if we need to recreate
        the HTML page.

        """
        m = Hasher()
        m.update(fr.source().encode("utf-8"))
        add_data_to_hash(data, fr.filename, m)
        this_hash = m.hexdigest()

        file_info = self.files.setdefault(rootname, FileInfo())

        if this_hash == file_info.hash:
            # Nothing has changed to require the file to be reported again.
            return True
        else:
            # File has changed, record the latest hash and force regeneration.
            file_info.hash = this_hash
            return False

    def index_info(self, fname: str) -> IndexItem:
        """Get the information for index.html for `fname`."""
        return self.files.get(fname, FileInfo()).index

    def set_index_info(self, fname: str, info: IndexItem) -> None:
        """Set the information for index.html for `fname`."""
        self.files.setdefault(fname, FileInfo()).index = info


# Helpers for templates and generating HTML

def escape(t: str) -> str:
    """HTML-escape the text in `t`.

    This is only suitable for HTML text, not attributes.

    """
    # Convert HTML special chars into HTML entities.
    return t.replace("&", "&amp;").replace("<", "&lt;")


def pair(ratio: tuple[int, int]) -> str:
    """Format a pair of numbers so JavaScript can read them in an attribute."""
    return "{} {}".format(*ratio)
