# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt

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

import datetime
import json
import os
import re
import shutil

import coverage
from coverage import env
from coverage.backward import iitems
from coverage.files import flat_rootname
from coverage.misc import CoverageException, Hasher, isolate_module
from coverage.report import Reporter
from coverage.results import Numbers
from coverage.templite import Templite

os = isolate_module(os)


# Static files are looked for in a list of places.
STATIC_PATH = [
    # The place Debian puts system Javascript libraries.
    "/usr/share/javascript",

    # Our htmlfiles directory.
    os.path.join(os.path.dirname(__file__), "htmlfiles"),
]


def data_filename(fname, pkgdir=""):
    """Return the path to a data file of ours.

    The file is searched for on `STATIC_PATH`, and the first place it's found,
    is returned.

    Each directory in `STATIC_PATH` is searched as-is, and also, if `pkgdir`
    is provided, at that sub-directory.

    """
    tried = []
    for static_dir in STATIC_PATH:
        static_filename = os.path.join(static_dir, fname)
        if os.path.exists(static_filename):
            return static_filename
        else:
            tried.append(static_filename)
        if pkgdir:
            static_filename = os.path.join(static_dir, pkgdir, fname)
            if os.path.exists(static_filename):
                return static_filename
            else:
                tried.append(static_filename)
    raise CoverageException(
        "Couldn't find static file %r from %r, tried: %r" % (fname, os.getcwd(), tried)
    )


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


class HtmlReporter(Reporter):
    """HTML reporting."""

    # These files will be copied from the htmlfiles directory to the output
    # directory.
    STATIC_FILES = [
        ("style.css", ""),
        ("jquery.min.js", "jquery"),
        ("jquery.debounce.min.js", "jquery-debounce"),
        ("jquery.hotkeys.js", "jquery-hotkeys"),
        ("jquery.isonscreen.js", "jquery-isonscreen"),
        ("jquery.tablesorter.min.js", "jquery-tablesorter"),
        ("coverage_html.js", ""),
        ("keybd_closed.png", ""),
        ("keybd_open.png", ""),
    ]

    def __init__(self, cov, config):
        super(HtmlReporter, self).__init__(cov, config)
        self.directory = None
        title = self.config.html_title
        if env.PY2:
            title = title.decode("utf8")
        self.template_globals = {
            'escape': escape,
            'pair': pair,
            'title': title,
            '__url__': coverage.__url__,
            '__version__': coverage.__version__,
        }
        self.source_tmpl = Templite(
            data("pyfile.html"), self.template_globals
        )

        self.coverage = cov

        self.files = []
        self.has_arcs = self.coverage.data.has_arcs()
        self.status = HtmlStatus()
        self.extra_css = None
        self.totals = Numbers()
        self.time_stamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')

    def report(self, morfs):
        """Generate an HTML report for `morfs`.

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

        """
        assert self.config.html_dir, "must give a directory for html reporting"

        # Read the status data.
        self.status.read(self.config.html_dir)

        # Check that this run used the same settings as the last run.
        m = Hasher()
        m.update(self.config)
        these_settings = m.hexdigest()
        if self.status.settings_hash() != these_settings:
            self.status.reset()
            self.status.set_settings_hash(these_settings)

        # The user may have extra CSS they want copied.
        if self.config.extra_css:
            self.extra_css = os.path.basename(self.config.extra_css)

        # Process all the files.
        self.report_files(self.html_file, morfs, self.config.html_dir)

        if not self.files:
            raise CoverageException("No data to report.")

        # Write the index file.
        self.index_file()

        self.make_local_static_report_files()
        return self.totals.n_statements and self.totals.pc_covered

    def make_local_static_report_files(self):
        """Make local instances of static files for HTML report."""
        # The files we provide must always be copied.
        for static, pkgdir in self.STATIC_FILES:
            shutil.copyfile(
                data_filename(static, pkgdir),
                os.path.join(self.directory, static)
            )

        # The user may have extra CSS they want copied.
        if self.extra_css:
            shutil.copyfile(
                self.config.extra_css,
                os.path.join(self.directory, self.extra_css)
            )

    def write_html(self, fname, html):
        """Write `html` to `fname`, properly encoded."""
        with open(fname, "wb") as fout:
            fout.write(html.encode('ascii', 'xmlcharrefreplace'))

    def file_hash(self, source, fr):
        """Compute a hash that changes if the file needs to be re-reported."""
        m = Hasher()
        m.update(source)
        self.coverage.data.add_to_hash(fr.filename, m)
        return m.hexdigest()

    def html_file(self, fr, analysis):
        """Generate an HTML file for one source file."""
        source = fr.source()

        # Find out if the file on disk is already correct.
        rootname = flat_rootname(fr.relative_filename())
        this_hash = self.file_hash(source.encode('utf-8'), fr)
        that_hash = self.status.file_hash(rootname)
        if this_hash == that_hash:
            # Nothing has changed to require the file to be reported again.
            self.files.append(self.status.index_info(rootname))
            return

        self.status.set_file_hash(rootname, this_hash)

        # Get the numbers for this file.
        nums = analysis.numbers

        if self.has_arcs:
            missing_branch_arcs = analysis.missing_branch_arcs()

        # These classes determine which lines are highlighted by default.
        c_run = "run hide_run"
        c_exc = "exc"
        c_mis = "mis"
        c_par = "par " + c_run

        lines = []

        for lineno, line in enumerate(fr.source_token_lines(), start=1):
            # Figure out how to mark this line.
            line_class = []
            annotate_html = ""
            annotate_title = ""
            if lineno in analysis.statements:
                line_class.append("stm")
            if lineno in analysis.excluded:
                line_class.append(c_exc)
            elif lineno in analysis.missing:
                line_class.append(c_mis)
            elif self.has_arcs and lineno in missing_branch_arcs:
                line_class.append(c_par)
                shorts = []
                longs = []
                for b in missing_branch_arcs[lineno]:
                    if b < 0:
                        shorts.append("exit")
                        longs.append("the function exit")
                    else:
                        shorts.append(b)
                        longs.append("line %d" % b)
                # 202F is NARROW NO-BREAK SPACE.
                # 219B is RIGHTWARDS ARROW WITH STROKE.
                short_fmt = "%s&#x202F;&#x219B;&#x202F;%s"
                annotate_html = ",&nbsp;&nbsp; ".join(short_fmt % (lineno, d) for d in shorts)
                annotate_html += " [?]"

                annotate_title = "Line %d was executed, but never jumped to " % lineno
                if len(longs) == 1:
                    annotate_title += longs[0]
                elif len(longs) == 2:
                    annotate_title += longs[0] + " or " + longs[1]
                else:
                    annotate_title += ", ".join(longs[:-1]) + ", or " + longs[-1]
            elif lineno in analysis.statements:
                line_class.append(c_run)

            # Build the HTML for the line.
            html = []
            for tok_type, tok_text in line:
                if tok_type == "ws":
                    html.append(escape(tok_text))
                else:
                    tok_html = escape(tok_text) or '&nbsp;'
                    html.append(
                        '<span class="%s">%s</span>' % (tok_type, tok_html)
                    )

            lines.append({
                'html': ''.join(html),
                'number': lineno,
                'class': ' '.join(line_class) or "pln",
                'annotate': annotate_html,
                'annotate_title': annotate_title,
            })

        # Write the HTML page for this file.
        template_values = {
            'c_exc': c_exc, 'c_mis': c_mis, 'c_par': c_par, 'c_run': c_run,
            'has_arcs': self.has_arcs, 'extra_css': self.extra_css,
            'fr': fr, 'nums': nums, 'lines': lines,
            'time_stamp': self.time_stamp,
        }
        html = spaceless(self.source_tmpl.render(template_values))

        html_filename = rootname + ".html"
        html_path = os.path.join(self.directory, html_filename)
        self.write_html(html_path, html)

        # Save this file's information for the index file.
        index_info = {
            'nums': nums,
            'html_filename': html_filename,
            'relative_filename': fr.relative_filename(),
        }
        self.files.append(index_info)
        self.status.set_index_info(rootname, index_info)

    def index_file(self):
        """Write the index.html file for this report."""
        index_tmpl = Templite(data("index.html"), self.template_globals)

        self.totals = sum(f['nums'] for f in self.files)

        html = index_tmpl.render({
            'has_arcs': self.has_arcs,
            'extra_css': self.extra_css,
            'files': self.files,
            'totals': self.totals,
            'time_stamp': self.time_stamp,
        })

        self.write_html(os.path.join(self.directory, "index.html"), html)

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


class HtmlStatus(object):
    """The status information we keep to support incremental reporting."""

    STATUS_FILE = "status.json"
    STATUS_FORMAT = 1

    #           pylint: disable=wrong-spelling-in-comment,useless-suppression
    #  The data looks like:
    #
    #  {
    #      'format': 1,
    #      'settings': '540ee119c15d52a68a53fe6f0897346d',
    #      'version': '4.0a1',
    #      'files': {
    #          'cogapp___init__': {
    #              'hash': 'e45581a5b48f879f301c0f30bf77a50c',
    #              'index': {
    #                  'html_filename': 'cogapp___init__.html',
    #                  'name': 'cogapp/__init__',
    #                  'nums': <coverage.results.Numbers object at 0x10ab7ed0>,
    #              }
    #          },
    #          ...
    #          'cogapp_whiteutils': {
    #              'hash': '8504bb427fc488c4176809ded0277d51',
    #              'index': {
    #                  'html_filename': 'cogapp_whiteutils.html',
    #                  'name': 'cogapp/whiteutils',
    #                  'nums': <coverage.results.Numbers object at 0x10ab7d90>,
    #              }
    #          },
    #      },
    #  }

    def __init__(self):
        self.reset()

    def reset(self):
        """Initialize to empty."""
        self.settings = ''
        self.files = {}

    def read(self, directory):
        """Read the last status in `directory`."""
        usable = False
        try:
            status_file = os.path.join(directory, self.STATUS_FILE)
            with open(status_file, "r") as fstatus:
                status = json.load(fstatus)
        except (IOError, ValueError):
            usable = False
        else:
            usable = True
            if status['format'] != self.STATUS_FORMAT:
                usable = False
            elif status['version'] != coverage.__version__:
                usable = False

        if usable:
            self.files = {}
            for filename, fileinfo in iitems(status['files']):
                fileinfo['index']['nums'] = Numbers(*fileinfo['index']['nums'])
                self.files[filename] = fileinfo
            self.settings = status['settings']
        else:
            self.reset()

    def write(self, directory):
        """Write the current status to `directory`."""
        status_file = os.path.join(directory, self.STATUS_FILE)
        files = {}
        for filename, fileinfo in iitems(self.files):
            fileinfo['index']['nums'] = fileinfo['index']['nums'].init_args()
            files[filename] = fileinfo

        status = {
            'format': self.STATUS_FORMAT,
            'version': coverage.__version__,
            'settings': self.settings,
            'files': files,
        }
        with open(status_file, "w") as fout:
            json.dump(status, fout)

        # Older versions of ShiningPanda look for the old name, status.dat.
        # Accomodate them if we are running under Jenkins.
        # https://issues.jenkins-ci.org/browse/JENKINS-28428
        if "JENKINS_URL" in os.environ:
            with open(os.path.join(directory, "status.dat"), "w") as dat:
                dat.write("https://issues.jenkins-ci.org/browse/JENKINS-28428\n")

    def settings_hash(self):
        """Get the hash of the coverage.py settings."""
        return self.settings

    def set_settings_hash(self, settings):
        """Set the hash of the coverage.py settings."""
        self.settings = settings

    def file_hash(self, fname):
        """Get the hash of `fname`'s contents."""
        return self.files.get(fname, {}).get('hash', '')

    def set_file_hash(self, fname, val):
        """Set the hash of `fname`'s contents."""
        self.files.setdefault(fname, {})['hash'] = val

    def index_info(self, fname):
        """Get the information for index.html for `fname`."""
        return self.files.get(fname, {}).get('index', {})

    def set_index_info(self, fname, info):
        """Set the information for index.html for `fname`."""
        self.files.setdefault(fname, {})['index'] = info


# Helpers for templates and generating HTML

def escape(t):
    """HTML-escape the text in `t`."""
    return (
        t
        # Convert HTML special chars into HTML entities.
        .replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
        .replace("'", "&#39;").replace('"', "&quot;")
        # Convert runs of spaces: "......" -> "&nbsp;.&nbsp;.&nbsp;."
        .replace("  ", "&nbsp; ")
        # To deal with odd-length runs, convert the final pair of spaces
        # so that "....." -> "&nbsp;.&nbsp;&nbsp;."
        .replace("  ", "&nbsp; ")
    )


def spaceless(html):
    """Squeeze out some annoying extra space from an HTML string.

    Nicely-formatted templates mean lots of extra space in the result.
    Get rid of some.

    """
    html = re.sub(r">\s+<p ", ">\n<p ", html)
    return html


def pair(ratio):
    """Format a pair of numbers so JavaScript can read them in an attribute."""
    return "%s %s" % ratio
