# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Touch firmware test report in html format."""

import os
import urllib

import common_util
import firmware_log
import test_conf as conf

from firmware_utils import get_fw_and_date
from string import Template


class TemplateHtml:
    """An html Template."""

    def __init__(self, image_width, image_height, score_colors):
        self.score_colors = score_colors

        # Define the template of the doc
        self.doc = Template('$head $summary $logs $tail')
        self.table = Template('<table border="3" width="100%"> $gestures '
                              '</table>')
        self.gestures = []

        # Define a template to show a gesture information including
        # the gesture name, variation, prompt, image, and test results.
        self.gesture_template = Template('''
            <tr>
                <td><table>
                    <tr>
                        <h3> $gesture_name.$variation </h3>
                        <h5> $prompt </h5>
                    </tr>
                    <tr>
                        <img src="data:image/png;base64,\n$image"
                            alt="$filename" width="%d" height="%d" />
                    </tr>
                </table></td>
                <td><table>
                    $vlogs
                </table></td>
            </tr>
        ''' % (image_width, image_height))

        self.validator_template =  Template('''
            <tr>
<pre><span style="color:$color"><b>$name</b></span>
$details
    criteria: $criteria
<span style="color:$color"><b>score: $score</b></span></pre>
            </tr>
        ''')

        self.detail_template =  Template('<tr><h5> $detail </h5></tr>')
        self._fill_doc()

    def _html_head(self):
        """Fill the head of an html document."""
        head = '\n'.join(['<!DOCTYPE html>', '<html>', '<body>'])
        return head

    def _html_tail(self):
        """Fill the tail of an html document."""
        tail = '\n'.join(['</body>', '</html>'])
        return tail

    def _fill_doc(self):
        """Fill in fields into the doc."""
        self.doc = Template(self.doc.safe_substitute(head=self._html_head(),
                                                     tail=self._html_tail()))

    def get_score_color(self, score):
        """Present the score in different colors."""
        for s, c in self.score_colors:
            if score >= s:
                return c

    def _insert_details(self, details):
        details_content = []
        for detail in details:
            details_content.append(' ' * 4 + detail.strip())
        return '<br>'.join(details_content)

    def _insert_vlog(self, vlog):
        """Insert a single vlog."""
        vlog_content = self.validator_template.safe_substitute(
                name=vlog.name,
                details=self._insert_details(vlog.details),
                criteria=vlog.criteria,
                color=self.get_score_color(vlog.score),
                score=vlog.score)
        return vlog_content

    def _insert_vlogs(self, vlogs):
        """Insert multiple vlogs."""
        vlogs_content = []
        for vlog in vlogs:
            vlogs_content.append(self._insert_vlog(vlog))
        return '<hr>'.join(vlogs_content)

    def insert_gesture(self, glog, image, image_filename):
        """Insert glog, image, and vlogs."""
        vlogs_content = self._insert_vlogs(glog.vlogs)
        gesture = self.gesture_template.safe_substitute(
                gesture_name=glog.name,
                variation=glog.variation,
                prompt=glog.prompt,
                image=image,
                filename=image_filename,
                vlogs=vlogs_content)
        self.gestures.append(gesture)

    def get_doc(self):
        gestures = ''.join(self.gestures)
        new_table = self.table.safe_substitute(gestures=gestures)
        new_doc = self.doc.safe_substitute(logs=new_table)
        return new_doc


class ReportHtml:
    """Firmware Report in html format."""

    def __init__(self, filename, screen_size, touch_device_window_size,
                 score_colors):
        self.html_filename = filename
        self.screen_size = screen_size
        self.image_width = self.screen_size[0] * 0.5
        touch_width, touch_height = touch_device_window_size
        self.image_height = self.image_width / touch_width * touch_height
        self.doc = TemplateHtml(self.image_width, self.image_height,
                                score_colors)
        self._reset_content()
        fw_and_date = get_fw_and_date(filename)
        self.rlog = firmware_log.RoundLog(*fw_and_date)

    def __del__(self):
        self.stop()

    def stop(self):
        """Close the file."""
        with open(self.html_filename, 'w') as report_file:
            report_file.write(self.doc.get_doc())
        # Make a copy to /tmp so that it could be viewed in Chrome.
        tmp_copy = os.path.join(conf.docroot,
                                os.path.basename(self.html_filename))
        copy_cmd = 'cp %s %s' % (self.html_filename, tmp_copy)
        common_util.simple_system(copy_cmd)

        # Dump the logs to a byte stream file
        log_file_root = os.path.splitext(self.html_filename)[0]
        log_filename = os.extsep.join([log_file_root, 'log'])
        self.rlog.dump(log_filename)

    def _reset_content(self):
        self.glog = firmware_log.GestureLog()
        self.encoded_image=''
        self.image_filename=''

    def _get_content(self):
        return [self.glog, self.encoded_image, self.image_filename]

    def _encode_base64(self, filename):
        """Encode a file in base 64 format."""
        if (filename is None) or (not os.path.isfile(filename)):
            return None
        encoded = urllib.quote(open(filename, "rb").read().encode("base64"))
        return encoded

    def flush(self):
        """Flush the current gesture including gesture log, image and
        validator logs.
        """
        content = self._get_content()
        # It is ok to flush the gesture log even when there are no mtplot images
        if self.glog:
            # Write the content to the html file.
            self.doc.insert_gesture(*content)
            # Write the logs to the round log.
            self.rlog.insert_glog(self.glog)
            self._reset_content()

    def insert_image(self, filename):
        """Insert an image into the document."""
        self.encoded_image = self._encode_base64(filename)
        self.image_filename = filename

    def insert_result(self, text):
        """Insert the text into the document."""
        self.result += text

    def insert_gesture_log(self, glog):
        """Update the gesture log."""
        self.glog = glog

    def insert_validator_logs(self, vlogs):
        """Update the validator logs."""
        self.glog.vlogs = vlogs
