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

import base64
import json
import os
import sys

import common

BLINK_TOOLS_DIR = os.path.join(common.SRC_DIR, 'third_party', 'blink', 'tools')
WEB_TESTS_DIR = os.path.join(BLINK_TOOLS_DIR, os.pardir, 'web_tests')
EXTERNAL_WPT_TESTS_DIR = os.path.join(WEB_TESTS_DIR, 'external', 'wpt')

if BLINK_TOOLS_DIR not in sys.path:
    sys.path.append(BLINK_TOOLS_DIR)

from blinkpy.common.host import Host
from blinkpy.common.html_diff import html_diff
from blinkpy.common.system.filesystem import FileSystem
from blinkpy.common.unified_diff import unified_diff
from blinkpy.web_tests.models import test_failures

class BaseWptScriptAdapter(common.BaseIsolatedScriptArgsAdapter):
    """The base class for script adapters that use wptrunner to execute web
    platform tests. This contains any code shared between these scripts, such
    as integrating output with the results viewer. Subclasses contain other
    (usually platform-specific) logic."""

    def __init__(self, host=None):
        super(BaseWptScriptAdapter, self).__init__()
        if not host:
            host = Host()
        self.fs = host.filesystem
        self.port = host.port_factory.get()
        self.wpt_manifest = self.port.wpt_manifest("external/wpt")
        # Path to the output of the test run. Comes from the args passed to the
        # run, parsed after this constructor. Can be overwritten by tests.
        self.wpt_output = None

    def generate_test_output_args(self, output):
        return ['--log-chromium', output]

    def generate_sharding_args(self, total_shards, shard_index):
        return ['--total-chunks=%d' % total_shards,
                # shard_index is 0-based but WPT's this-chunk to be 1-based
                '--this-chunk=%d' % (shard_index + 1),
                # The default sharding strategy is to shard by directory. But
                # we want to hash each test to determine which shard runs it.
                # This allows running individual directories that have few
                # tests across many shards.
                '--chunk-type=hash']

    def do_post_test_run_tasks(self):
        if not self.wpt_output and self.options:
            self.wpt_output = self.options.isolated_script_test_output

        # Move json results into layout-test-results directory
        results_dir = os.path.dirname(self.wpt_output)
        layout_test_results = os.path.join(results_dir, 'layout-test-results')
        if self.fs.exists(layout_test_results):
            self.fs.rmtree(layout_test_results)
        self.fs.maybe_make_directory(layout_test_results)

        # Perform post-processing of wptrunner output
        self.process_wptrunner_output(
            os.path.join(layout_test_results, 'full_results.json'),
            os.path.join(layout_test_results, 'full_results_jsonp.js'),
            # NOTE: Despite the name, this is actually a JSONP file.
            # https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/tools/blinkpy/web_tests/controllers/manager.py;l=636;drc=3b93609b2498af0e9dc298f64e2b4f6204af68fa
            os.path.join(layout_test_results, 'failing_results.json'),
        )

        # Copy layout test results viewer to layout-test-results directory
        self.fs.copyfile(
            os.path.join(WEB_TESTS_DIR, 'fast', 'harness', 'results.html'),
            os.path.join(layout_test_results, 'results.html'))

    def process_wptrunner_output(self,
                                 full_results_json,
                                 full_results_jsonp,
                                 failing_results_jsonp):
        """Post-process the output generated by wptrunner.

        This output contains a single large json file containing the raw content
        or artifacts which need to be extracted into their own files and removed
        from the json file (to avoid duplication)."""
        # output_json is modified *in place* throughout this function.
        with self.fs.open_text_file_for_reading(self.wpt_output) as f:
            output_json = json.load(f)
        results_dir = os.path.dirname(self.wpt_output)
        self._process_test_leaves(results_dir, output_json['path_delimiter'],
                                  output_json['tests'], '')
        # Write output_json back to the same file after modifying it in memory
        full_results = json.dumps(output_json)
        self.fs.write_text_file(self.wpt_output, full_results)
        # Also copy to full_results.json
        self.fs.copyfile(self.wpt_output, full_results_json)

        # JSONP paddings need to be the same as
        # https://source.chromium.org/chromium/chromium/src/+/master:third_party/blink/tools/blinkpy/web_tests/controllers/manager.py;l=629;drc=3b93609b2498af0e9dc298f64e2b4f6204af68fa
        # Write to full_results.jsonp
        with self.fs.open_text_file_for_writing(full_results_jsonp) as f:
            f.write('ADD_FULL_RESULTS(')
            f.write(full_results)
            f.write(');')
        # Trim the results and write to failing_results.jsonp
        self._trim_to_regressions(output_json['tests'])
        with self.fs.open_text_file_for_writing(failing_results_jsonp) as f:
            f.write('ADD_RESULTS(')
            json.dump(output_json, f)
            f.write(');')

    def _handle_text_outputs(self, actual_metadata, root_node, results_dir,
                             path_so_far):
        """Produces actual, expected and diff text outputs."""
        # If the test passed, there are no artifacts to output. Note that if a
        # baseline file (*.ini file) exists, an actual of PASS means that the
        # test matched the baseline, not that the test itself passed. As such,
        # we still correctly produce artifacts in the case where someone fixes a
        # baselined test.
        if root_node["actual"] == "PASS":
            return

        # Note that the actual_metadata is a list of strings, so we join
        # them on new lines when writing to file.
        actual_text = "\n".join(actual_metadata)
        actual_subpath = self._write_text_artifact(
            test_failures.FILENAME_SUFFIX_ACTUAL,
            results_dir, path_so_far, actual_text)
        root_node["artifacts"]["actual_text"] = [actual_subpath]
        # Try to locate the expected output of this test, if it exists.
        expected_subpath, expected_text = \
            self._maybe_write_expected_output(results_dir, path_so_far)
        if expected_subpath:
            root_node["artifacts"]["expected_text"] = [expected_subpath]

        diff_content = unified_diff(expected_text, actual_text,
                                    expected_subpath, actual_subpath)
        diff_subpath = self._write_text_artifact(
            test_failures.FILENAME_SUFFIX_DIFF, results_dir,
            path_so_far, diff_content)
        root_node["artifacts"]["text_diff"] = [diff_subpath]
        # We pass the text as bytes here because the html_diff library
        # requires that but the file contents is read-in as unicode.
        html_diff_content = html_diff(expected_text.encode('utf-8'),
                                      actual_text.encode('utf-8'))
        # Ensure the diff itself is properly decoded, to avoid
        # UnicodeDecodeErrors when writing to file. This can happen if
        # the diff contains unicode characters but the file is written
        # as ascii because of the default system-level encoding.
        html_diff_content = unicode(html_diff_content, 'utf-8')
        html_diff_subpath = self._write_text_artifact(
            test_failures.FILENAME_SUFFIX_HTML_DIFF, results_dir,
            path_so_far, html_diff_content, extension=".html")
        root_node["artifacts"]["pretty_text_diff"] = [html_diff_subpath]

    def _process_test_leaves(self, results_dir, delim, root_node, path_so_far):
        """Finds and processes each test leaf below the specified root.

        This will recursively traverse the trie of results in the json output,
        keeping track of the path to each test and identifying leaves by the
        presence of certain attributes.

        Args:
            results_dir: str path to the dir that results are stored
            delim: str delimiter to be used for test names
            root_node: dict representing the root of the trie we're currently
                looking at
            path_so_far: str the path to the current root_node in the trie
        """
        if "actual" in root_node:
            # Found a leaf, process it
            if "artifacts" not in root_node:
                return

            actual_metadata = root_node["artifacts"].pop(
                "wpt_actual_metadata", None)
            if actual_metadata:
                self._handle_text_outputs(
                    actual_metadata, root_node, results_dir, path_so_far)

            screenshot_artifact = root_node["artifacts"].pop(
                "screenshots", None)
            if screenshot_artifact:
                screenshot_paths_dict = self._write_screenshot_artifact(
                    results_dir, path_so_far, screenshot_artifact)
                for screenshot_key, path in screenshot_paths_dict.items():
                    root_node["artifacts"][screenshot_key] = [path]

            log_artifact = root_node["artifacts"].pop("wpt_log", None)
            if log_artifact:
                artifact_subpath = self._write_text_artifact(
                    test_failures.FILENAME_SUFFIX_STDERR,
                    results_dir, path_so_far, "\n".join(log_artifact))
                if artifact_subpath:
                    # Required by fast/harness/results.html to show stderr.
                    root_node["has_stderr"] = True
                    root_node["artifacts"]["stderr"] = [artifact_subpath]

            crashlog_artifact = root_node["artifacts"].pop(
                "wpt_crash_log", None)
            if crashlog_artifact:
                # Note that the crashlog_artifact is a list of strings, so we
                # join them on new lines when writing to file.
                artifact_subpath = self._write_text_artifact(
                    test_failures.FILENAME_SUFFIX_CRASH_LOG,
                    results_dir, path_so_far, "\n".join(crashlog_artifact))
                if artifact_subpath:
                    root_node["artifacts"]["crash_log"] = [artifact_subpath]

            return

        # We're not at a leaf node, continue traversing the trie.
        for key in root_node:
            # Append the key to the path, separated by the delimiter. However if
            # the path is empty, skip the delimiter to avoid a leading slash in
            # the path.
            new_path = path_so_far + delim + key if path_so_far else key
            self._process_test_leaves(results_dir, delim, root_node[key],
                                      new_path)

    def _maybe_write_expected_output(self, results_dir, test_name):
        """Attempts to create an expected output artifact for the test.

        The expected output of tests is checked-in to the source tree beside the
        test itself, with a .ini extension. Not all tests have expected output.

        Args:
            results_dir: str path to the dir to write the output to
            test_name: str name of the test to write expected output for

        Returns:
            two strings:
            - first is the path to the artifact file that the expected output
              was written to, relative to the directory that the original output
              is located. Returns None if there is no expected output for this
              test.
            - second is the text that is written to the file, or empty string if
              there is no expected output for this test.
        """
        test_file_subpath = self.wpt_manifest.file_path_for_test_url(test_name)
        if not test_file_subpath:
            # Not all tests in the output have a corresponding test file. This
            # could be print-reftests (which are unsupported by the blinkpy
            # manifest) or .any.js tests (which appear in the output even though
            # they do not actually run - they have corresponding tests like
            # .any.worker.html which are covered here).
            return None, ""

        test_file_path = os.path.join(EXTERNAL_WPT_TESTS_DIR, test_file_subpath)
        expected_ini_path = test_file_path + ".ini"
        if not self.fs.exists(expected_ini_path):
            return None, ""

        # This test has checked-in expected output. It needs to be copied to the
        # results viewer directory and renamed from <test>.ini to
        # <test>-expected.txt
        contents = self.fs.read_text_file(expected_ini_path)
        artifact_subpath = self._write_text_artifact(
            test_failures.FILENAME_SUFFIX_EXPECTED, results_dir, test_name,
            contents)
        return artifact_subpath, contents

    def _trim_to_regressions(self, root_node):
        """Finds and processes each test leaf below the specified root.

        This will recursively traverse the trie of results in the json output,
        deleting leaves with is_unexpected=true.

        Args:
            root_node: dict representing the root of the trie we're currently
                looking at

        Returns:
            A boolean, whether to delete the current root_node.
        """
        if "actual" in root_node:
            # Found a leaf. Delete it if it's not a regression (unexpected
            # failures).
            return not root_node.get("is_regression")

        # Not a leaf, recurse into the subtree
        for key, node in root_node.items():
            if self._trim_to_regressions(node):
                del root_node[key]

        # Delete the current node if empty.
        return len(root_node) == 0


    def _write_text_artifact(self, suffix, results_dir, test_name, artifact,
                             extension=".txt"):
        """Writes a text artifact to disk.

        A text artifact contains some form of text output for a test, such as
        the actual test output, or a diff of the actual and expected outputs.
        It is written to a txt file with a suffix generated from the log type.

        Args:
            suffix: str suffix of the artifact to write, e.g.
                test_failures.FILENAME_SUFFIX_ACTUAL
            results_dir: str path to the directory that results live in
            test_name: str name of the test that this artifact is for
            artifact: string, the text to write for this test.
            extension: str the filename extension to use. Defaults to ".txt" but
                can be changed if needed (eg: to ".html" for pretty-diff)

        Returns:
            string, the path to the artifact file that was written relative
              to the |results_dir|.
        """
        log_artifact_sub_path = (
            os.path.join("layout-test-results",
                         self.port.output_filename(
                             test_name, suffix, extension))
        )
        log_artifact_full_path = os.path.join(results_dir,
                                              log_artifact_sub_path)
        if not self.fs.exists(os.path.dirname(log_artifact_full_path)):
            self.fs.maybe_make_directory(
                os.path.dirname(log_artifact_full_path))
        self.fs.write_text_file(log_artifact_full_path, artifact)

        return log_artifact_sub_path

    def _write_screenshot_artifact(self, results_dir, test_name,
                                   screenshot_artifact):
        """Write screenshot artifact to disk.

        The screenshot artifact is a list of strings, each of which has the
        format <url>:<base64-encoded PNG>. Each url-png pair is a screenshot of
        either the test, or one of its refs. We can identify which screenshot is
        for the test by comparing the url piece to the test name.

        Args:
           results_dir: str path to the directory that results live in
           test:name str name of the test that this artifact is for
           screenshot_artifact: list of strings, each being a url-png pair as
               described above.

        Returns:
             A dict mapping the screenshot key (ie: actual, expected) to the
             path of the file for that screenshot
        """
        result={}
        for screenshot_pair in screenshot_artifact:
            screenshot_split = screenshot_pair.split(":")
            url = screenshot_split[0]
            # The url produced by wptrunner will have a leading / which we trim
            # away for easier comparison to the test_name below.
            if url.startswith("/"):
                url = url[1:]
            image_bytes = base64.b64decode(screenshot_split[1].strip())

            screenshot_key = "expected_image"
            file_suffix = test_failures.FILENAME_SUFFIX_EXPECTED
            if test_name == url:
                screenshot_key = "actual_image"
                file_suffix = test_failures.FILENAME_SUFFIX_ACTUAL

            screenshot_sub_path = (
                os.path.join("layout-test-results",
                             self.port.output_filename(
                                 test_name, file_suffix, ".png"))
            )
            result[screenshot_key] = screenshot_sub_path

            screenshot_full_path = os.path.join(results_dir,screenshot_sub_path)
            if not self.fs.exists(os.path.dirname(screenshot_full_path)):
                self.fs.maybe_make_directory(
                    os.path.dirname(screenshot_full_path))
            # Note: we are writing raw bytes to this file
            self.fs.write_binary_file(screenshot_full_path, image_bytes)
        return result
