#!/usr/bin/env python

# Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
# Copyright (C) 2015 Canon Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above
#    copyright notice, this list of conditions and the following
#    disclaimer.
# 2. Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials
#    provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

"""
 This script imports W3C tests into WebKit, either from a local folder or by cloning W3C CSS and WPT repositories.

 This script will import the tests into WebKit following these rules:

    - All tests are by default imported into LayoutTests/imported/w3c

    - Tests will be imported into a directory tree that mirrors WPT repository in LayoutTests/imported/w3c/web-platform-tests.

    - By default, only reftests and jstest are imported. This can be overridden with a -a or --all
      argument

    - Also by default, if test files by the same name already exist in the destination directory,
      they are overwritten with the idea that running this script would refresh files periodically.
      This can also be overridden by a -n or --no-overwrite flag

    - If no import_directory is provided, the script will download the tests from the W3C github repositories.
      The selection of tests and folders to import will be based on the following files:
         1. LayoutTests/imported/w3c/resources/TestRepositories lists the repositories to clone, the corresponding revision to checkout and the infrastructure folders that need to be imported/skipped.
         2. LayoutTests/imported/w3c/resources/ImportExpectations list the test suites or tests to NOT import.

    - All files are converted to work in WebKit:
         1. Paths to testharness.js files are modified to point to Webkit's copy of them in
            LayoutTests/resources, using the correct relative path from the new location.
            This is applied to CSS tests but not to WPT tests.
         2. All CSS properties requiring the -webkit-vendor prefix are prefixed - this current
            list of what needs prefixes is read from Source/WebCore/CSS/CSSProperties.in
         3. Each reftest has its own copy of its reference file following the naming conventions
            new-run-webkit-tests expects
         4. If a reference files lives outside the directory of the test that uses it, it is checked
            for paths to support files as it will be imported into a different relative position to the
            test file (in the same directory)

     - Upon completion, script outputs the total number tests imported, broken down by test type

     - Also upon completion, each directory where files are imported will have w3c-import.log written
       with a timestamp, the list of CSS properties used that require prefixes, the list of imported files,
       and guidance for future test modification and maintenance.

     - On subsequent imports, this file is read to determine if files have been removed in the newer changesets.
       The script removes these files accordingly.
"""

import argparse
import json
import logging
import mimetypes

from webkitpy.common.host import Host
from webkitpy.common.system.filesystem import FileSystem
from webkitpy.common.webkit_finder import WebKitFinder
from webkitpy.w3c.common import WPT_GH_URL, WPTPaths
from webkitpy.w3c.test_parser import TestParser
from webkitpy.w3c.test_converter import convert_for_webkit
from webkitpy.w3c.test_downloader import TestDownloader

CHANGESET_NOT_AVAILABLE = 'Not Available'

_log = logging.getLogger(__name__)


def main(_argv, _stdout, _stderr):
    options, test_paths = parse_args(_argv)

    configure_logging()

    test_importer = TestImporter(Host(), test_paths, options)
    test_importer.do_import()


def configure_logging():
    class LogHandler(logging.StreamHandler):

        def format(self, record):
            if record.levelno > logging.INFO:
                return "%s: %s" % (record.levelname, record.getMessage())
            return record.getMessage()

    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    handler = LogHandler()
    handler.setLevel(logging.INFO)
    logger.addHandler(handler)
    return handler


# FIXME: We should decide whether we want to make this specific to web-platform-tests or to make it generic to any git repository containing tests.
def parse_args(args):
    description = """
To import a web-platform-tests test suite named xyz, use: 'import-w3c-tests web-platform-tests/xyz'.
To import a web-platform-tests suite from a specific folder, use 'import-w3c-tests xyz -l -s my-folder-containing-web-platform-tests-folder'"""
    parser = argparse.ArgumentParser(prog='import-w3c-tests [web-platform-tests/test-suite-name...]', description=description, formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument('-n', '--no-overwrite', dest='overwrite', action='store_false', default=True,
        help='Flag to prevent duplicate test files from overwriting existing tests. By default, they will be overwritten')
    parser.add_argument('-l', '--no-links-conversion', dest='convert_test_harness_links', action='store_false', default=True,
       help='Do not change links (testharness js or css e.g.). This option only applies when providing a source directory, in which case by default, links are converted to point to WebKit testharness files. When tests are downloaded from W3C repository, links are converted for CSS tests and remain unchanged for WPT tests')

    parser.add_argument('-t', '--tip-of-tree', dest='use_tip_of_tree', action='store_true', default=False,
        help='Import all tests using the latest repository revision')

    parser.add_argument('-a', '--all', action='store_true', default=False,
        help='Import all tests including reftests, JS tests, and manual/pixel tests. By default, only reftests and JS tests are imported')
    fs = FileSystem()
    parser.add_argument('-d', '--dest-dir', dest='destination', default=fs.join('imported', 'w3c'),
        help='Import into a specified directory relative to the LayoutTests root. By default, imports into imported/w3c')

    parser.add_argument('-s', '--src-dir', dest='source', default=None,
        help='Import from a specific folder which contains web-platform-tests folder. If not provided, the script will clone the necessary repositories.')

    parser.add_argument('-v', '--verbose', action='store_true', default=False,
         help='Print maximal log')
    parser.add_argument('--no-fetch', action='store_false', dest='fetch', default=True,
         help='Do not fetch the repositories. By default, repositories are fetched if a source directory is not provided')
    parser.add_argument('--import-all', action='store_true', default=False,
         help='Ignore the import-expectations.json file. All tests will be imported. This option only applies when tests are downloaded from W3C repository')

    parser.add_argument('--clean-dest-dir', action='store_true', dest='clean_destination_directory', default=False,
         help='Clean destination directory. All files in the destination directory will be deleted except for WebKit specific files (test expectations, .gitignore...) before new tests import. Dangling test expectations (expectation file that is no longer related to a test) are removed after tests import.')

    options, args = parser.parse_known_args(args)
    return options, args


class TestImporter(object):

    def __init__(self, host, test_paths, options):
        self.host = host
        self.source_directory = options.source
        self.options = options
        self.test_paths = test_paths if test_paths else []

        self.filesystem = self.host.filesystem

        webkit_finder = WebKitFinder(self.filesystem)
        self._webkit_root = webkit_finder.webkit_base()

        self.destination_directory = webkit_finder.path_from_webkit_base("LayoutTests", options.destination)
        self.tests_w3c_relative_path = self.filesystem.join('imported', 'w3c')
        self.layout_tests_path = webkit_finder.path_from_webkit_base('LayoutTests')
        self.layout_tests_w3c_path = self.filesystem.join(self.layout_tests_path, self.tests_w3c_relative_path)
        self.tests_download_path = WPTPaths.checkout_directory(webkit_finder)

        self._test_downloader = None

        self._potential_test_resource_files = []

        self.import_list = []
        self._importing_downloaded_tests = self.source_directory is None

        self._test_resource_files_json_path = self.filesystem.join(self.layout_tests_w3c_path, "resources", "resource-files.json")
        self._test_resource_files = json.loads(self.filesystem.read_text_file(self._test_resource_files_json_path)) if self.filesystem.exists(self._test_resource_files_json_path) else None

        self._tests_options_json_path = self.filesystem.join(self.layout_tests_path, 'tests-options.json')
        self._tests_options = json.loads(self.filesystem.read_text_file(self._tests_options_json_path)) if self.filesystem.exists(self._tests_options_json_path) else None
        self._slow_tests = []

        if self.options.clean_destination_directory and self._test_resource_files:
            self._test_resource_files["files"] = []
            if self._tests_options:
                self.remove_slow_from_w3c_tests_options()

        self.globalToSuffix = dict(
            window='html',
            worker='worker.html',
            dedicatedworker='worker.html',
            serviceworker='serviceworker.html')

    def do_import(self):
        if not self.source_directory:
            _log.info('Downloading W3C test repositories')
            self.source_directory = self.filesystem.join(self.tests_download_path, 'to-be-imported')
            self.filesystem.maybe_make_directory(self.tests_download_path)
            self.filesystem.maybe_make_directory(self.source_directory)
            self.test_downloader().download_tests(self.source_directory, self.test_paths, self.options.use_tip_of_tree)

        test_paths = self.test_paths if self.test_paths else [test_repository['name'] for test_repository in self.test_downloader().test_repositories]
        for test_path in test_paths:
            self.find_importable_tests(self.filesystem.join(self.source_directory, test_path))

        if self.options.clean_destination_directory:
            for test_path in test_paths:
                self.clean_destination_directory(test_path)

        self.import_tests()

        for test_path in test_paths:
            self.remove_dangling_expectations(test_path)

        if self._importing_downloaded_tests:
            self.generate_git_submodules_description_for_all_repositories()

        self.test_downloader().update_import_expectations(self.test_paths)

    def generate_git_submodules_description_for_all_repositories(self):
        for test_repository in self._test_downloader.test_repositories:
            if 'generate_git_submodules_description' in test_repository['import_options']:
                self.filesystem.maybe_make_directory(self.filesystem.join(self.destination_directory, 'resources'))
                self._test_downloader.generate_git_submodules_description(test_repository, self.filesystem.join(self.destination_directory, 'resources', test_repository['name'] + '-modules.json'))
            if 'generate_gitignore' in test_repository['import_options']:
                self._test_downloader.generate_gitignore(test_repository, self.destination_directory)
            if 'generate_init_py' in test_repository['import_options']:
                self.write_init_py(self.filesystem.join(self.destination_directory, test_repository['name'], '__init__.py'))

    def write_init_py(self, filepath):
        self.filesystem.write_text_file(filepath, '# This file is required for Python to search this directory for modules.')

    def test_downloader(self):
        if not self._test_downloader:
            download_options = TestDownloader.default_options()
            download_options.fetch = self.options.fetch
            download_options.verbose = self.options.verbose
            download_options.import_all = self.options.import_all
            self._test_downloader = TestDownloader(self.tests_download_path, self.host, download_options)
        return self._test_downloader

    def should_skip_file(self, filename):
        # For some reason the w3c repo contains random perl scripts we don't care about.
        if filename.endswith('.pl'):
            return True
        if filename.startswith('.'):
            return not filename == '.htaccess'
        return False

    def _is_baseline(self, filesystem, dirname, filename):
        return filename.endswith('-expected.txt')

    def _should_remove_before_importing(self, filesystem, dirname, filename):
        if self._is_baseline(filesystem, dirname, filename):
            return False
        if filename.startswith("."):
            return False
        return True

    def clean_destination_directory(self, filename):
        directory = self.filesystem.join(self.destination_directory, filename)
        for relative_path in self.filesystem.files_under(directory, file_filter=self._should_remove_before_importing):
            self.filesystem.remove(self.filesystem.join(directory, relative_path))

    def remove_dangling_expectations(self, filename):
        #FIXME: Clean also the expected files stored in all platform specific folders.
        directory = self.filesystem.join(self.destination_directory, filename)
        for relative_path in self.filesystem.files_under(directory, file_filter=self._is_baseline):
            path = self.filesystem.join(directory, relative_path)
            if self.filesystem.glob(path.replace('-expected.txt', '*')) == [path]:
                self.filesystem.remove(path)

    def _source_root_directory_for_path(self, path):
        if not self._importing_downloaded_tests:
            return self.source_directory
        for test_repository in self.test_downloader().load_test_repositories(self.filesystem):
            source_directory = self.filesystem.join(self.source_directory, test_repository['name'])
            if path.startswith(source_directory):
                return source_directory

    def find_importable_tests(self, directory):
        def should_keep_subdir(filesystem, path):
            if self._importing_downloaded_tests:
                return True
            subdir = path[len(directory):]
            DIRS_TO_SKIP = ('work-in-progress', 'tools', 'support')
            should_skip = filesystem.basename(subdir).startswith('.') or (subdir in DIRS_TO_SKIP)
            return not should_skip

        source_root_directory = self._source_root_directory_for_path(directory)
        directories = self.filesystem.dirs_under(directory, should_keep_subdir)
        for root in directories:
            _log.info('Scanning ' + root + '...')
            total_tests = 0
            reftests = 0
            jstests = 0

            copy_list = []

            for filename in self.filesystem.listdir(root):
                if self.filesystem.isdir(self.filesystem.join(root, filename)):
                    continue
                # FIXME: This block should really be a separate function, but the early-continues make that difficult.

                if self.should_skip_file(filename):
                    continue

                fullpath = self.filesystem.join(root, filename)

                mimetype = mimetypes.guess_type(fullpath)
                if not 'html' in str(mimetype[0]) and not 'application/xhtml+xml' in str(mimetype[0]) and not 'application/xml' in str(mimetype[0]):
                    copy_list.append({'src': fullpath, 'dest': filename})
                    continue

                test_parser = TestParser(vars(self.options), filename=fullpath, host=self.host, source_root_directory=source_root_directory)
                test_info = test_parser.analyze_test()
                if test_info is None:
                    # This is probably a resource file, but we should generate WPT manifest instead and get the list of resource files from it.
                    if not self._is_in_resources_directory(fullpath):
                        self._potential_test_resource_files.append(fullpath)
                    copy_list.append({'src': fullpath, 'dest': filename})
                    continue
                elif self._is_in_resources_directory(fullpath):
                    _log.warning('%s is a test located in a "resources" folder. This test will be skipped by WebKit test runners.', fullpath)

                if 'manualtest' in test_info.keys():
                    continue

                if 'slow' in test_info:
                    self._slow_tests.append(fullpath)

                if 'referencefile' in test_info.keys():
                    # Skip it since, the corresponding reference test should have a link to this file
                    continue

                if 'reference' in test_info.keys():
                    reftests += 1
                    total_tests += 1
                    test_basename = self.filesystem.basename(test_info['test'])

                    # Add the ref file, following WebKit style.
                    # FIXME: Ideally we'd support reading the metadata
                    # directly rather than relying  on a naming convention.
                    # Using a naming convention creates duplicate copies of the
                    # reference files.
                    ref_file = self.filesystem.splitext(test_basename)[0] + '-expected'
                    ref_file += self.filesystem.splitext(test_info['reference'])[1]

                    copy_list.append({'src': test_info['reference'], 'dest': ref_file, 'reference_support_info': test_info['reference_support_info']})
                    copy_list.append({'src': test_info['test'], 'dest': filename})

                elif 'jstest' in test_info.keys():
                    jstests += 1
                    total_tests += 1
                    copy_list.append({'src': fullpath, 'dest': filename})
                else:
                    total_tests += 1
                    copy_list.append({'src': fullpath, 'dest': filename})

            if copy_list:
                # Only add this directory to the list if there's something to import
                self.import_list.append({'dirname': root, 'copy_list': copy_list,
                    'reftests': reftests, 'jstests': jstests, 'total_tests': total_tests})

    def should_convert_test_harness_links(self, test):
        if self._importing_downloaded_tests:
            for test_repository in self.test_downloader().test_repositories:
                if test.startswith(test_repository['name']):
                    return 'convert_test_harness_links' in test_repository['import_options']
            return True
        return self.options.convert_test_harness_links

    def _webkit_test_runner_options(self, path):
        if not(self.filesystem.isfile(path)):
            return ''

        options_prefix = '<!-- webkit-test-runner'
        contents = ''
        try:
            contents = self.filesystem.read_text_file(path).split('\n')
        except:
            _log.info('unable to read %s as a text file' % path)

        if not len(contents):
            return ''
        first_line = contents[0]

        return first_line[first_line.index(options_prefix):] if options_prefix in first_line else ''

    def _add_webkit_test_runner_options_to_content(self, content, webkit_test_runner_options):
        lines = content.split('\n')
        if not len(lines):
            return ''
        lines[0] = lines[0] + webkit_test_runner_options
        return '\n'.join(lines)

    def _copy_html_file(self, source_filepath, new_filepath):
        webkit_test_runner_options = self._webkit_test_runner_options(new_filepath)
        if not webkit_test_runner_options:
            self.filesystem.copyfile(source_filepath, new_filepath)
            return

        source_content = self.filesystem.read_text_file(source_filepath)
        self.filesystem.write_text_file(new_filepath, self._add_webkit_test_runner_options_to_content(source_content, webkit_test_runner_options))

    def _write_html_template(self, new_filepath):
        webkit_test_runner_options = self._webkit_test_runner_options(new_filepath)
        content = '<!-- This file is required for WebKit test infrastructure to run the templated test -->'
        self.filesystem.write_text_file(new_filepath, content + webkit_test_runner_options)

    def readEnvironmentsForTemplateTest(self, filepath):
        environments = []
        lines = self.filesystem.read_text_file(filepath).split('\n')
        for line in lines:
            if line.startswith('//') and 'META: global=' in line:
                items = line.split('META: global=', 1)[1].split(',')
                suffixes = [self.globalToSuffix.get(item.strip(), '') for item in items]
                environments = list(filter(None, set(suffixes)))
        return set(environments) if len(environments) else ['html', 'worker.html']

    def write_html_files_for_templated_js_tests(self, orig_filepath, new_filepath):
        if (orig_filepath.endswith('.window.js')):
            self._write_html_template(new_filepath.replace('.window.js', '.window.html'))
            return
        if (orig_filepath.endswith('.worker.js')):
            self._write_html_template(new_filepath.replace('.worker.js', '.worker.html'))
            return
        if (orig_filepath.endswith('.any.js')):
            for suffix in self.readEnvironmentsForTemplateTest(orig_filepath):
                self._write_html_template(new_filepath.replace('.any.js', '.any.' + suffix))
            return

    def import_tests(self):
        total_imported_tests = 0
        total_imported_reftests = 0
        total_imported_jstests = 0
        total_prefixed_properties = {}
        total_prefixed_property_values = {}

        failed_conversion_files = []

        # We currently need to rewrite css web-platform-tests because they use a separate "reference" folder for
        # their ref-tests' results.
        folders_needing_file_rewriting = ['web-platform-tests/']

        for dir_to_copy in self.import_list:
            total_imported_tests += dir_to_copy['total_tests']
            total_imported_reftests += dir_to_copy['reftests']
            total_imported_jstests += dir_to_copy['jstests']

            prefixed_properties = []
            prefixed_property_values = []

            if not dir_to_copy['copy_list']:
                continue

            orig_path = dir_to_copy['dirname']

            subpath = self.filesystem.relpath(orig_path, self.source_directory)
            new_path = self.filesystem.join(self.destination_directory, subpath)

            should_rewrite_files = False
            for folder_needing_file_rewriting in folders_needing_file_rewriting:
                if subpath.startswith(folder_needing_file_rewriting):
                    should_rewrite_files = True
                    break

            if not(self.filesystem.exists(new_path)):
                self.filesystem.maybe_make_directory(new_path)

            copied_files = []

            for file_to_copy in dir_to_copy['copy_list']:
                # FIXME: Split this block into a separate function.
                orig_filepath = self.filesystem.normpath(file_to_copy['src'])

                if self.filesystem.isdir(orig_filepath):
                    # FIXME: Figure out what is triggering this and what to do about it.
                    _log.error('%s refers to a directory' % orig_filepath)
                    continue

                if not(self.filesystem.exists(orig_filepath)):
                    _log.warning('%s not found. Possible error in the test.', orig_filepath)
                    continue

                new_filepath = self.filesystem.join(new_path, file_to_copy['dest'])
                if 'reference_support_info' in file_to_copy.keys() and file_to_copy['reference_support_info'] != {}:
                    reference_support_info = file_to_copy['reference_support_info']
                else:
                    reference_support_info = None

                if not(self.filesystem.exists(self.filesystem.dirname(new_filepath))):
                    self.filesystem.maybe_make_directory(self.filesystem.dirname(new_filepath))

                if not self.options.overwrite and self.filesystem.exists(new_filepath):
                    _log.info('Skipping import of existing file ' + new_filepath)
                else:
                    # FIXME: Maybe doing a file diff is in order here for existing files?
                    # In other words, there's no sense in overwriting identical files, but
                    # there's no harm in copying the identical thing.
                    _log.info('Importing: %s', orig_filepath)
                    _log.info('       As: %s', new_filepath)

                # Only html, xml, or css should be converted
                # FIXME: Eventually, so should js when support is added for this type of conversion
                mimetype = mimetypes.guess_type(orig_filepath)
                if should_rewrite_files and ('text/' in str(mimetype[0]) or 'application/' in str(mimetype[0])) \
                                        and ('html' in str(mimetype[0]) or 'xml' in str(mimetype[0])  or 'css' in str(mimetype[0]) or 'javascript' in str(mimetype[0])):
                    _log.info("Rewriting: %s" % new_filepath)
                    try:
                        converted_file = convert_for_webkit(new_path, filename=orig_filepath, reference_support_info=reference_support_info, host=self.host, convert_test_harness_links=self.should_convert_test_harness_links(subpath), webkit_test_runner_options=self._webkit_test_runner_options(new_filepath))
                    except:
                        _log.warn('Failed converting %s', orig_filepath)
                        failed_conversion_files.append(orig_filepath)
                        converted_file = None

                    if not converted_file:
                        self.filesystem.copyfile(orig_filepath, new_filepath)  # The file was unmodified.
                    else:
                        for prefixed_property in converted_file[0]:
                            total_prefixed_properties.setdefault(prefixed_property, 0)
                            total_prefixed_properties[prefixed_property] += 1

                        prefixed_properties.extend(set(converted_file[0]) - set(prefixed_properties))

                        for prefixed_value in converted_file[1]:
                            total_prefixed_property_values.setdefault(prefixed_value, 0)
                            total_prefixed_property_values[prefixed_value] += 1

                        prefixed_property_values.extend(set(converted_file[1]) - set(prefixed_property_values))

                        self.filesystem.write_binary_file(new_filepath, converted_file[2])
                elif orig_filepath.endswith('__init__.py') and not self.filesystem.getsize(orig_filepath):
                    # Some bots dislike empty __init__.py.
                    self.write_init_py(new_filepath)
                elif 'html' in str(mimetype[0]):
                    self._copy_html_file(orig_filepath, new_filepath)
                else:
                    self.filesystem.copyfile(orig_filepath, new_filepath)

                self.write_html_files_for_templated_js_tests(orig_filepath, new_filepath)

                copied_files.append(new_filepath.replace(self._webkit_root, ''))

            self.remove_deleted_files(new_path, copied_files)
            self.write_import_log(new_path, copied_files, prefixed_properties, prefixed_property_values)

        _log.info('Import complete')

        _log.info('IMPORTED %d TOTAL TESTS', total_imported_tests)
        _log.info('Imported %d reftests', total_imported_reftests)
        _log.info('Imported %d JS tests', total_imported_jstests)
        _log.info('Imported %d pixel/manual tests', total_imported_tests - total_imported_jstests - total_imported_reftests)
        if len(failed_conversion_files):
            _log.warn('Failed converting %d files (files copied without being converted)', len(failed_conversion_files))
        _log.info('')
        _log.info('Properties needing prefixes (by count):')

        for prefixed_property in sorted(total_prefixed_properties, key=lambda p: total_prefixed_properties[p]):
            _log.info('  %s: %s', prefixed_property, total_prefixed_properties[prefixed_property])
        _log.info('')
        _log.info('Property values needing prefixes (by count):')

        for prefixed_value in sorted(total_prefixed_property_values, key=lambda p: total_prefixed_property_values[p]):
            _log.info('  %s: %s', prefixed_value, total_prefixed_property_values[prefixed_value])

        if self._potential_test_resource_files and self._test_resource_files:
            # FIXME: We should check that actual tests are not in the test_resource_files list
            should_update_json_file = False
            files = self._test_resource_files["files"]
            for full_path in self._potential_test_resource_files:
                resource_file_path = self.filesystem.relpath(full_path, self.source_directory)
                if not self._already_identified_as_resource_file(resource_file_path):
                    files.append(resource_file_path)
                    should_update_json_file = True
            if should_update_json_file:
                files.sort()
                self.filesystem.write_text_file(self._test_resource_files_json_path, json.dumps(self._test_resource_files, sort_keys=True, indent=4).replace(' \n', '\n'))

        if self._tests_options:
            self.update_tests_options()

    def _already_identified_as_resource_file(self, path):
        if not self._test_resource_files:
            return False
        if path in self._test_resource_files["files"]:
            return True
        return any([path.find(directory) != -1 for directory in self._test_resource_files["directories"]])

    def _is_in_resources_directory(self, path):
        return "resources" in path.split(self.filesystem.sep)

    def update_tests_options(self):
        should_update = self.options.clean_destination_directory
        for full_path in self._slow_tests:
            w3c_test_path = self.filesystem.relpath(full_path, self.source_directory)
            print(w3c_test_path)
            # No need to mark tests as slow if they are in skipped directories
            if self._already_identified_as_resource_file(w3c_test_path):
                continue

            test_path = self.filesystem.join(self.tests_w3c_relative_path, w3c_test_path)
            options = self._tests_options.get(test_path, [])
            if not 'slow' in options:
                options.append('slow')
                self._tests_options[test_path] = options
                should_update = True

        if should_update:
            self.filesystem.write_text_file(self._tests_options_json_path, json.dumps(self._tests_options, sort_keys=True, indent=4).replace(' \n', '\n'))

    def remove_slow_from_w3c_tests_options(self):
        for test_path in self._tests_options.keys():
            if self.tests_w3c_relative_path in test_path:
                options = self._tests_options[test_path]
                options.remove('slow')
                if not options:
                    self._tests_options.pop(test_path)

    def remove_deleted_files(self, import_directory, new_file_list):
        """ Reads an import log in |import_directory|, compares it to the |new_file_list|, and removes files not in the new list."""

        previous_file_list = []

        import_log_file = self.filesystem.join(import_directory, 'w3c-import.log')
        if not self.filesystem.exists(import_log_file):
            return

        contents = self.filesystem.read_text_file(import_log_file).split('\n')

        if 'List of files:' in contents:
            list_index = contents.index('List of files:') + 1
            previous_file_list = [filename.strip() for filename in contents[list_index:] if len(filename)]

        deleted_files = set(previous_file_list) - set(new_file_list)
        for deleted_file in deleted_files:
            _log.info('Deleting file removed from the W3C repo: %s', deleted_file)
            deleted_file = self.filesystem.join(self._webkit_root, deleted_file[1:])
            if not self.filesystem.exists(deleted_file):
                _log.warning('%s no longer exists', deleted_file)
                continue
            self.filesystem.remove(deleted_file)

    def write_import_log(self, import_directory, file_list, prop_list, property_values_list):
        """ Writes a w3c-import.log file in each directory with imported files. """

        import_log = []
        import_log.append('The tests in this directory were imported from the W3C repository.\n')
        import_log.append('Do NOT modify these tests directly in WebKit.\n')
        import_log.append('Instead, create a pull request on the WPT github:\n')
        import_log.append('\t%s\n\n' % WPT_GH_URL)
        import_log.append('Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport\n\n')
        import_log.append('Do NOT modify or remove this file.\n\n')
        import_log.append('------------------------------------------------------------------------\n')
        import_log.append('Properties requiring vendor prefixes:\n')
        if prop_list:
            for prop in prop_list:
                import_log.append(prop + '\n')
        else:
            import_log.append('None\n')
        import_log.append('Property values requiring vendor prefixes:\n')
        if property_values_list:
            for value in property_values_list:
                import_log.append(value + '\n')
        else:
            import_log.append('None\n')
        import_log.append('------------------------------------------------------------------------\n')
        import_log.append('List of files:\n')
        for item in sorted(file_list):
            import_log.append(item + '\n')

        self.filesystem.write_text_file(self.filesystem.join(import_directory, 'w3c-import.log'), ''.join(import_log))
