# -*- coding: utf-8 -*-
#                     The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
""" This module is responsible to generate 'index.html' for the report.

The input for this step is the output directory, where individual reports
could be found. It parses those reports and generates 'index.html'. """

import re
import os
import os.path
import sys
import shutil
import plistlib
import glob
import json
import logging
import datetime
from libscanbuild import duplicate_check
from libscanbuild.clang import get_version

__all__ = ['document']


def document(args):
    """ Generates cover report and returns the number of bugs/crashes. """

    html_reports_available = args.output_format in {'html', 'plist-html'}

    logging.debug('count crashes and bugs')
    crash_count = sum(1 for _ in read_crashes(args.output))
    bug_counter = create_counters()
    for bug in read_bugs(args.output, html_reports_available):
        bug_counter(bug)
    result = crash_count + bug_counter.total

    if html_reports_available and result:
        use_cdb = os.path.exists(args.cdb)

        logging.debug('generate index.html file')
        # common prefix for source files to have sorter path
        prefix = commonprefix_from(args.cdb) if use_cdb else os.getcwd()
        # assemble the cover from multiple fragments
        fragments = []
        try:
            if bug_counter.total:
                fragments.append(bug_summary(args.output, bug_counter))
                fragments.append(bug_report(args.output, prefix))
            if crash_count:
                fragments.append(crash_report(args.output, prefix))
            assemble_cover(args, prefix, fragments)
            # copy additional files to the report
            copy_resource_files(args.output)
            if use_cdb:
                shutil.copy(args.cdb, args.output)
        finally:
            for fragment in fragments:
                os.remove(fragment)
    return result


def assemble_cover(args, prefix, fragments):
    """ Put together the fragments into a final report. """

    import getpass
    import socket

    if args.html_title is None:
        args.html_title = os.path.basename(prefix) + ' - analyzer results'

    with open(os.path.join(args.output, 'index.html'), 'w') as handle:
        indent = 0
        handle.write(reindent("""
        |<!DOCTYPE html>
        |<html>
        |  <head>
        |    <title>{html_title}</title>
        |    <link type="text/css" rel="stylesheet" href="scanview.css"/>
        |    <script type='text/javascript' src="sorttable.js"></script>
        |    <script type='text/javascript' src='selectable.js'></script>
        |  </head>""", indent).format(html_title=args.html_title))
        handle.write(comment('SUMMARYENDHEAD'))
        handle.write(reindent("""
        |  <body>
        |    <h1>{html_title}</h1>
        |    <table>
        |      <tr><th>User:</th><td>{user_name}@{host_name}</td></tr>
        |      <tr><th>Working Directory:</th><td>{current_dir}</td></tr>
        |      <tr><th>Command Line:</th><td>{cmd_args}</td></tr>
        |      <tr><th>Clang Version:</th><td>{clang_version}</td></tr>
        |      <tr><th>Date:</th><td>{date}</td></tr>
        |    </table>""", indent).format(html_title=args.html_title,
                                         user_name=getpass.getuser(),
                                         host_name=socket.gethostname(),
                                         current_dir=prefix,
                                         cmd_args=' '.join(sys.argv),
                                         clang_version=get_version(args.clang),
                                         date=datetime.datetime.today(
                                         ).strftime('%c')))
        for fragment in fragments:
            # copy the content of fragments
            with open(fragment, 'r') as input_handle:
                shutil.copyfileobj(input_handle, handle)
        handle.write(reindent("""
        |  </body>
        |</html>""", indent))


def bug_summary(output_dir, bug_counter):
    """ Bug summary is a HTML table to give a better overview of the bugs. """

    name = os.path.join(output_dir, 'summary.html.fragment')
    with open(name, 'w') as handle:
        indent = 4
        handle.write(reindent("""
        |<h2>Bug Summary</h2>
        |<table>
        |  <thead>
        |    <tr>
        |      <td>Bug Type</td>
        |      <td>Quantity</td>
        |      <td class="sorttable_nosort">Display?</td>
        |    </tr>
        |  </thead>
        |  <tbody>""", indent))
        handle.write(reindent("""
        |    <tr style="font-weight:bold">
        |      <td class="SUMM_DESC">All Bugs</td>
        |      <td class="Q">{0}</td>
        |      <td>
        |        <center>
        |          <input checked type="checkbox" id="AllBugsCheck"
        |                 onClick="CopyCheckedStateToCheckButtons(this);"/>
        |        </center>
        |      </td>
        |    </tr>""", indent).format(bug_counter.total))
        for category, types in bug_counter.categories.items():
            handle.write(reindent("""
        |    <tr>
        |      <th>{0}</th><th colspan=2></th>
        |    </tr>""", indent).format(category))
            for bug_type in types.values():
                handle.write(reindent("""
        |    <tr>
        |      <td class="SUMM_DESC">{bug_type}</td>
        |      <td class="Q">{bug_count}</td>
        |      <td>
        |        <center>
        |          <input checked type="checkbox"
        |                 onClick="ToggleDisplay(this,'{bug_type_class}');"/>
        |        </center>
        |      </td>
        |    </tr>""", indent).format(**bug_type))
        handle.write(reindent("""
        |  </tbody>
        |</table>""", indent))
        handle.write(comment('SUMMARYBUGEND'))
    return name


def bug_report(output_dir, prefix):
    """ Creates a fragment from the analyzer reports. """

    pretty = prettify_bug(prefix, output_dir)
    bugs = (pretty(bug) for bug in read_bugs(output_dir, True))

    name = os.path.join(output_dir, 'bugs.html.fragment')
    with open(name, 'w') as handle:
        indent = 4
        handle.write(reindent("""
        |<h2>Reports</h2>
        |<table class="sortable" style="table-layout:automatic">
        |  <thead>
        |    <tr>
        |      <td>Bug Group</td>
        |      <td class="sorttable_sorted">
        |        Bug Type
        |        <span id="sorttable_sortfwdind">&nbsp;&#x25BE;</span>
        |      </td>
        |      <td>File</td>
        |      <td>Function/Method</td>
        |      <td class="Q">Line</td>
        |      <td class="Q">Path Length</td>
        |      <td class="sorttable_nosort"></td>
        |    </tr>
        |  </thead>
        |  <tbody>""", indent))
        handle.write(comment('REPORTBUGCOL'))
        for current in bugs:
            handle.write(reindent("""
        |    <tr class="{bug_type_class}">
        |      <td class="DESC">{bug_category}</td>
        |      <td class="DESC">{bug_type}</td>
        |      <td>{bug_file}</td>
        |      <td class="DESC">{bug_function}</td>
        |      <td class="Q">{bug_line}</td>
        |      <td class="Q">{bug_path_length}</td>
        |      <td><a href="{report_file}#EndPath">View Report</a></td>
        |    </tr>""", indent).format(**current))
            handle.write(comment('REPORTBUG', {'id': current['report_file']}))
        handle.write(reindent("""
        |  </tbody>
        |</table>""", indent))
        handle.write(comment('REPORTBUGEND'))
    return name


def crash_report(output_dir, prefix):
    """ Creates a fragment from the compiler crashes. """

    pretty = prettify_crash(prefix, output_dir)
    crashes = (pretty(crash) for crash in read_crashes(output_dir))

    name = os.path.join(output_dir, 'crashes.html.fragment')
    with open(name, 'w') as handle:
        indent = 4
        handle.write(reindent("""
        |<h2>Analyzer Failures</h2>
        |<p>The analyzer had problems processing the following files:</p>
        |<table>
        |  <thead>
        |    <tr>
        |      <td>Problem</td>
        |      <td>Source File</td>
        |      <td>Preprocessed File</td>
        |      <td>STDERR Output</td>
        |    </tr>
        |  </thead>
        |  <tbody>""", indent))
        for current in crashes:
            handle.write(reindent("""
        |    <tr>
        |      <td>{problem}</td>
        |      <td>{source}</td>
        |      <td><a href="{file}">preprocessor output</a></td>
        |      <td><a href="{stderr}">analyzer std err</a></td>
        |    </tr>""", indent).format(**current))
            handle.write(comment('REPORTPROBLEM', current))
        handle.write(reindent("""
        |  </tbody>
        |</table>""", indent))
        handle.write(comment('REPORTCRASHES'))
    return name


def read_crashes(output_dir):
    """ Generate a unique sequence of crashes from given output directory. """

    return (parse_crash(filename)
            for filename in glob.iglob(os.path.join(output_dir, 'failures',
                                                    '*.info.txt')))


def read_bugs(output_dir, html):
    # type: (str, bool) -> Generator[Dict[str, Any], None, None]
    """ Generate a unique sequence of bugs from given output directory.

    Duplicates can be in a project if the same module was compiled multiple
    times with different compiler options. These would be better to show in
    the final report (cover) only once. """

    def empty(file_name):
        return os.stat(file_name).st_size == 0

    duplicate = duplicate_check(
        lambda bug: '{bug_line}.{bug_path_length}:{bug_file}'.format(**bug))

    # get the right parser for the job.
    parser = parse_bug_html if html else parse_bug_plist
    # get the input files, which are not empty.
    pattern = os.path.join(output_dir, '*.html' if html else '*.plist')
    bug_files = (file for file in glob.iglob(pattern) if not empty(file))

    for bug_file in bug_files:
        for bug in parser(bug_file):
            if not duplicate(bug):
                yield bug


def parse_bug_plist(filename):
    """ Returns the generator of bugs from a single .plist file. """

    content = plistlib.readPlist(filename)
    files = content.get('files')
    for bug in content.get('diagnostics', []):
        if len(files) <= int(bug['location']['file']):
            logging.warning('Parsing bug from "%s" failed', filename)
            continue

        yield {
            'result': filename,
            'bug_type': bug['type'],
            'bug_category': bug['category'],
            'bug_line': int(bug['location']['line']),
            'bug_path_length': int(bug['location']['col']),
            'bug_file': files[int(bug['location']['file'])]
        }


def parse_bug_html(filename):
    """ Parse out the bug information from HTML output. """

    patterns = [re.compile(r'<!-- BUGTYPE (?P<bug_type>.*) -->$'),
                re.compile(r'<!-- BUGFILE (?P<bug_file>.*) -->$'),
                re.compile(r'<!-- BUGPATHLENGTH (?P<bug_path_length>.*) -->$'),
                re.compile(r'<!-- BUGLINE (?P<bug_line>.*) -->$'),
                re.compile(r'<!-- BUGCATEGORY (?P<bug_category>.*) -->$'),
                re.compile(r'<!-- BUGDESC (?P<bug_description>.*) -->$'),
                re.compile(r'<!-- FUNCTIONNAME (?P<bug_function>.*) -->$')]
    endsign = re.compile(r'<!-- BUGMETAEND -->')

    bug = {
        'report_file': filename,
        'bug_function': 'n/a',  # compatibility with < clang-3.5
        'bug_category': 'Other',
        'bug_line': 0,
        'bug_path_length': 1
    }

    with open(filename) as handler:
        for line in handler.readlines():
            # do not read the file further
            if endsign.match(line):
                break
            # search for the right lines
            for regex in patterns:
                match = regex.match(line.strip())
                if match:
                    bug.update(match.groupdict())
                    break

    encode_value(bug, 'bug_line', int)
    encode_value(bug, 'bug_path_length', int)

    yield bug


def parse_crash(filename):
    """ Parse out the crash information from the report file. """

    match = re.match(r'(.*)\.info\.txt', filename)
    name = match.group(1) if match else None
    with open(filename, mode='rb') as handler:
        # this is a workaround to fix windows read '\r\n' as new lines.
        lines = [line.decode().rstrip() for line in handler.readlines()]
        return {
            'source': lines[0],
            'problem': lines[1],
            'file': name,
            'info': name + '.info.txt',
            'stderr': name + '.stderr.txt'
        }


def category_type_name(bug):
    """ Create a new bug attribute from bug by category and type.

    The result will be used as CSS class selector in the final report. """

    def smash(key):
        """ Make value ready to be HTML attribute value. """

        return bug.get(key, '').lower().replace(' ', '_').replace("'", '')

    return escape('bt_' + smash('bug_category') + '_' + smash('bug_type'))


def create_counters():
    """ Create counters for bug statistics.

    Two entries are maintained: 'total' is an integer, represents the
    number of bugs. The 'categories' is a two level categorisation of bug
    counters. The first level is 'bug category' the second is 'bug type'.
    Each entry in this classification is a dictionary of 'count', 'type'
    and 'label'. """

    def predicate(bug):
        bug_category = bug['bug_category']
        bug_type = bug['bug_type']
        current_category = predicate.categories.get(bug_category, dict())
        current_type = current_category.get(bug_type, {
            'bug_type': bug_type,
            'bug_type_class': category_type_name(bug),
            'bug_count': 0
        })
        current_type.update({'bug_count': current_type['bug_count'] + 1})
        current_category.update({bug_type: current_type})
        predicate.categories.update({bug_category: current_category})
        predicate.total += 1

    predicate.total = 0
    predicate.categories = dict()
    return predicate


def prettify_bug(prefix, output_dir):
    def predicate(bug):
        """ Make safe this values to embed into HTML. """

        bug['bug_type_class'] = category_type_name(bug)

        encode_value(bug, 'bug_file', lambda x: escape(chop(prefix, x)))
        encode_value(bug, 'bug_category', escape)
        encode_value(bug, 'bug_type', escape)
        encode_value(bug, 'report_file', lambda x: escape(chop(output_dir, x)))
        return bug

    return predicate


def prettify_crash(prefix, output_dir):
    def predicate(crash):
        """ Make safe this values to embed into HTML. """

        encode_value(crash, 'source', lambda x: escape(chop(prefix, x)))
        encode_value(crash, 'problem', escape)
        encode_value(crash, 'file', lambda x: escape(chop(output_dir, x)))
        encode_value(crash, 'info', lambda x: escape(chop(output_dir, x)))
        encode_value(crash, 'stderr', lambda x: escape(chop(output_dir, x)))
        return crash

    return predicate


def copy_resource_files(output_dir):
    """ Copy the javascript and css files to the report directory. """

    this_dir = os.path.dirname(os.path.realpath(__file__))
    for resource in os.listdir(os.path.join(this_dir, 'resources')):
        shutil.copy(os.path.join(this_dir, 'resources', resource), output_dir)


def encode_value(container, key, encode):
    """ Run 'encode' on 'container[key]' value and update it. """

    if key in container:
        value = encode(container[key])
        container.update({key: value})


def chop(prefix, filename):
    """ Create 'filename' from '/prefix/filename' """

    return filename if not len(prefix) else os.path.relpath(filename, prefix)


def escape(text):
    """ Paranoid HTML escape method. (Python version independent) """

    escape_table = {
        '&': '&amp;',
        '"': '&quot;',
        "'": '&apos;',
        '>': '&gt;',
        '<': '&lt;'
    }
    return ''.join(escape_table.get(c, c) for c in text)


def reindent(text, indent):
    """ Utility function to format html output and keep indentation. """

    result = ''
    for line in text.splitlines():
        if len(line.strip()):
            result += ' ' * indent + line.split('|')[1] + os.linesep
    return result


def comment(name, opts=dict()):
    """ Utility function to format meta information as comment. """

    attributes = ''
    for key, value in opts.items():
        attributes += ' {0}="{1}"'.format(key, value)

    return '<!-- {0}{1} -->{2}'.format(name, attributes, os.linesep)


def commonprefix_from(filename):
    """ Create file prefix from a compilation database entries. """

    with open(filename, 'r') as handle:
        return commonprefix(item['file'] for item in json.load(handle))


def commonprefix(files):
    """ Fixed version of os.path.commonprefix.

    :param files: list of file names.
    :return: the longest path prefix that is a prefix of all files. """
    result = None
    for current in files:
        if result is not None:
            result = os.path.commonprefix([result, current])
        else:
            result = current

    if result is None:
        return ''
    elif not os.path.isdir(result):
        return os.path.dirname(result)
    else:
        return os.path.abspath(result)
