#!/usr/bin/env python3
#===- symcov-report-server.py - Coverage Reports HTTP Serve --*- python -*--===#
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
#===------------------------------------------------------------------------===#
'''(EXPERIMENTAL) HTTP server to browse coverage reports from .symcov files.

Coverage reports for big binaries are too huge, generating them statically
makes no sense. Start the server and go to localhost:8001 instead.

Usage:
    ./tools/sancov/symcov-report-server.py \
            --symcov coverage_data.symcov \
            --srcpath root_src_dir

Other options:
    --port port_number - specifies the port to use (8001)
    --host host_name - host name to bind server to (127.0.0.1)
'''

from __future__ import print_function

import argparse
import http.server
import json
import socketserver
import time
import html
import os
import string
import math
import urllib

INDEX_PAGE_TMPL = """
<html>
<head>
  <title>Coverage Report</title>
  <style>
    .lz { color: lightgray; }
  </style>
</head>
<body>
    <table>
      <tr><th>File</th><th>Coverage</th></tr>
      <tr><td><em>Files with 0 coverage are not shown.</em></td></tr>
$filenames
    </table>
</body>
</html>
"""

CONTENT_PAGE_TMPL = """
<html>
<head>
  <title>$path</title>
  <style>
    .covered { background: lightgreen; }
    .not-covered { background: lightcoral; }
    .partially-covered { background: navajowhite; }
    .lz { color: lightgray; }
  </style>
</head>
<body>
<pre>
$content
</pre>
</body>
</html>
"""

class SymcovData:
    def __init__(self, symcov_json):
        self.covered_points = frozenset(symcov_json['covered-points'])
        self.point_symbol_info = symcov_json['point-symbol-info']
        self.file_coverage = self.compute_filecoverage()

    def filenames(self):
        return self.point_symbol_info.keys()

    def has_file(self, filename):
        return filename in self.point_symbol_info

    def compute_linemap(self, filename):
        """Build a line_number->css_class map."""
        points = self.point_symbol_info.get(filename, dict())

        line_to_points = dict()
        for fn, points in points.items():
            for point, loc in points.items():
                line = int(loc.split(":")[0])
                line_to_points.setdefault(line, []).append(point)

        result = dict()
        for line, points in line_to_points.items():
            status = "covered"
            covered_points = self.covered_points & set(points)
            if not len(covered_points):
                status = "not-covered"
            elif len(covered_points) != len(points):
                status = "partially-covered"
            result[line] = status
        return result

    def compute_filecoverage(self):
        """Build a filename->pct coverage."""
        result = dict()
        for filename, fns in self.point_symbol_info.items():
            file_points = []
            for fn, points in fns.items():
                file_points.extend(points.keys())
            covered_points = self.covered_points & set(file_points)
            result[filename] = int(math.ceil(
                len(covered_points) * 100 / len(file_points)))
        return result


def format_pct(pct):
    pct_str = str(max(0, min(100, pct)))
    zeroes = '0' * (3 - len(pct_str))
    if zeroes:
        zeroes = '<span class="lz">{0}</span>'.format(zeroes)
    return zeroes + pct_str

class ServerHandler(http.server.BaseHTTPRequestHandler):
    symcov_data = None
    src_path = None

    def do_GET(self):
        norm_path = os.path.normpath(urllib.parse.unquote(self.path[1:]))
        if self.path == '/':
            self.send_response(200)
            self.send_header("Content-type", "text/html; charset=utf-8")
            self.end_headers()

            filelist = []
            for filename in sorted(self.symcov_data.filenames()):
                file_coverage = self.symcov_data.file_coverage[filename]
                if not file_coverage:
                    continue
                filelist.append(
                        "<tr><td><a href=\"./{name}\">{name}</a></td>"
                        "<td>{coverage}%</td></tr>".format(
                            name=html.escape(filename, quote=True), 
                            coverage=format_pct(file_coverage)))

            response = string.Template(INDEX_PAGE_TMPL).safe_substitute(
                filenames='\n'.join(filelist))
            self.wfile.write(response.encode('UTF-8', 'replace'))
        elif self.symcov_data.has_file(norm_path):
            filename = norm_path
            filepath = os.path.join(self.src_path, filename) 
            if not os.path.exists(filepath):
                self.send_response(404)
                self.end_headers()
                return

            self.send_response(200)
            self.send_header("Content-type", "text/html; charset=utf-8")
            self.end_headers()

            linemap = self.symcov_data.compute_linemap(filename)

            with open(filepath, 'r', encoding='utf8') as f:
                content = "\n".join(
                        ["<span class='{cls}'>{line}&nbsp;</span>".format(
                            line=html.escape(line.rstrip()), 
                            cls=linemap.get(line_no, ""))
                            for line_no, line in enumerate(f, start=1)])

            response = string.Template(CONTENT_PAGE_TMPL).safe_substitute(
                path=self.path[1:],
                content=content)

            self.wfile.write(response.encode('UTF-8', 'replace'))
        else:
            self.send_response(404)
            self.end_headers()


def main():
    parser = argparse.ArgumentParser(description="symcov report http server.")
    parser.add_argument('--host', default='127.0.0.1')
    parser.add_argument('--port', default=8001)
    parser.add_argument('--symcov', required=True, type=argparse.FileType('r'))
    parser.add_argument('--srcpath', required=True)
    args = parser.parse_args()

    print("Loading coverage...")
    symcov_json = json.load(args.symcov)
    ServerHandler.symcov_data = SymcovData(symcov_json)
    ServerHandler.src_path = args.srcpath

    socketserver.TCPServer.allow_reuse_address = True
    httpd = socketserver.TCPServer((args.host, args.port), ServerHandler)
    print("Serving at {host}:{port}".format(host=args.host, port=args.port))
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()

if __name__ == '__main__':
    main()
