#!/usr/bin/env python

# Copyright (C) 2013 Adobe Systems Incorporated. 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.

import json
import logging
import os
import re
import sys

from webkitpy.common.host import Host
from webkitpy.common.webkit_finder import WebKitFinder

if sys.version_info > (3, 0):
    from html.parser import HTMLParser
else:
    from HTMLParser import HTMLParser

_log = logging.getLogger(__name__)


def convert_for_webkit(new_path, filename, reference_support_info, host=Host(), convert_test_harness_links=True, webkit_test_runner_options=''):
    """ Converts a file's |contents| so it will function correctly in its |new_path| in Webkit.

    Returns the list of modified properties and the modified text if the file was modifed, None otherwise."""
    contents = host.filesystem.read_text_file(filename)

    # WebKit does not have a www test domain.
    contents = contents.replace('{{domains[www]}}', '{{hosts[alt][]}}')

    converter = _W3CTestConverter(new_path, filename, reference_support_info, host, convert_test_harness_links, webkit_test_runner_options)
    if filename.endswith('.css'):
        return converter.add_webkit_prefix_to_unprefixed_properties_and_values(contents)
    elif filename.endswith('.js'):
        return ([], [], contents)
    else:
        converter.feed(contents)
        converter.close()
        return converter.output()


class _W3CTestConverter(HTMLParser):
    def __init__(self, new_path, filename, reference_support_info, host=Host(), convert_test_harness_links=True, webkit_test_runner_options=''):
        if sys.version_info > (3, 0):
            HTMLParser.__init__(self, convert_charrefs=False)
        else:
            HTMLParser.__init__(self)

        self._host = host
        self._filesystem = self._host.filesystem
        self._webkit_root = WebKitFinder(self._filesystem).webkit_base()

        self.converted_data = []
        self.converted_properties = []
        self.converted_property_values = []
        self.in_style_tag = False
        self.style_data = []
        self.filename = filename
        self.reference_support_info = reference_support_info
        self.webkit_test_runner_options = webkit_test_runner_options
        self.has_started = False

        resources_path = self.path_from_webkit_root('LayoutTests', 'resources')
        resources_relpath = self._filesystem.relpath(resources_path, new_path)
        self.new_test_harness_path = resources_relpath.replace(os.sep, '/')
        self.convert_test_harness_links = convert_test_harness_links

        # These settings might vary between WebKit and Blink
        css_property_file = self.path_from_webkit_root('Source', 'WebCore', 'css', 'CSSProperties.json')
        css_property_value_file = self.path_from_webkit_root('Source', 'WebCore', 'css', 'CSSValueKeywords.in')

        self.test_harness_re = re.compile('/resources/testharness')

        self.prefixed_properties = self.read_webkit_prefixed_css_property_list(css_property_file)
        prop_regex = r'([\s{]|^)(' + "|".join(prop.replace('-webkit-', '') for prop in self.prefixed_properties) + r')(\s+:|:)'
        self.prop_re = re.compile(prop_regex)

        self.prefixed_property_values = self.legacy_read_webkit_prefixed_css_property_list(css_property_value_file)
        prop_value_regex = r'(:\s*|^\s*)(' + "|".join(value.replace('-webkit-', '') for value in self.prefixed_property_values) + r')(\s*;|\s*}|\s*$)'
        self.prop_value_re = re.compile(prop_value_regex)

    def output(self):
        return (self.converted_properties, self.converted_property_values, ''.join(self.converted_data))

    def path_from_webkit_root(self, *comps):
        return self._filesystem.abspath(self._filesystem.join(self._webkit_root, *comps))

    def read_webkit_prefixed_css_property_list(self, file_name):
        contents = self._filesystem.read_text_file(file_name)
        if not contents:
            return []
        properties = json.loads(contents)['properties']
        property_names = []
        for property_name, property_dict in properties.items():
            property_names.append(property_name)
            if 'codegen-properties' in property_dict:
                codegen_options = property_dict['codegen-properties']
                if 'aliases' in codegen_options:
                    property_names.extend(codegen_options['aliases'])

        prefixed_properties = []
        unprefixed_properties = set()
        for property_name in property_names:
            # Find properties starting with the -webkit- prefix.
            match = re.match(r'-webkit-([\w|-]*)', property_name)
            if match:
                prefixed_properties.append(match.group(1))
            else:
                unprefixed_properties.add(property_name)

        # Ignore any prefixed properties for which an unprefixed version is supported
        return [prop for prop in prefixed_properties if prop not in unprefixed_properties]

    def legacy_read_webkit_prefixed_css_property_list(self, file_name):
        contents = self._filesystem.read_text_file(file_name)
        prefixed_properties = []
        unprefixed_properties = set()

        for line in contents.splitlines():
            if re.match('^(#|//)', line) or len(line.strip()) == 0:
                # skip comments and preprocessor directives and empty lines.
                continue
            # Property name is always first on the line.
            property_name = line.split(' ', 1)[0]
            # Find properties starting with the -webkit- prefix.
            match = re.match(r'-webkit-([\w|-]*)', property_name)
            if match:
                prefixed_properties.append(match.group(1))
            else:
                unprefixed_properties.add(property_name.strip())

        # Ignore any prefixed properties for which an unprefixed version is supported
        return [prop for prop in prefixed_properties if prop not in unprefixed_properties]

    def add_webkit_prefix_to_unprefixed_properties_and_values(self, text):
        """ Searches |text| for instances of properties and values requiring the -webkit- prefix and adds the prefix to them.

        Returns the list of converted properties, values and the modified text."""

        converted_properties = self.add_webkit_prefix_following_regex(text, self.prop_re)
        converted_property_values = self.add_webkit_prefix_following_regex(converted_properties[1], self.prop_value_re)

        # FIXME: Handle the JS versions of these properties and values and GetComputedStyle, too.
        return (converted_properties[0], converted_property_values[0], converted_property_values[1])

    def add_webkit_prefix_following_regex(self, text, regex):
        converted_list = set()
        text_chunks = []
        cur_pos = 0
        for m in regex.finditer(text):
            text_chunks.extend([text[cur_pos:m.start()], m.group(1), '-webkit-', m.group(2), m.group(3)])
            converted_list.add(m.group(2))
            cur_pos = m.end()
        text_chunks.append(text[cur_pos:])

        for item in converted_list:
            _log.info('  converting %s', item)

        return (converted_list, ''.join(text_chunks))

    def convert_reference_relpaths(self, text):
        """ Searches |text| for instances of files in reference_support_info and updates the relative path to be correct for the new ref file location"""
        converted = text
        for path in self.reference_support_info['files']:
            if converted.find(path) != -1:
                # FIXME: This doesn't handle an edge case where simply removing the relative path doesn't work.
                # See http://webkit.org/b/135677 for details.
                new_path = re.sub(re.escape(self.reference_support_info['reference_relpath']), '', path, 1)
                converted = re.sub(re.escape(path), new_path, converted)

        return converted

    def convert_style_data(self, data):
        converted = self.add_webkit_prefix_to_unprefixed_properties_and_values(data)
        if converted[0]:
            self.converted_properties.extend(list(converted[0]))
        if converted[1]:
            self.converted_property_values.extend(list(converted[1]))

        if self.reference_support_info is None or self.reference_support_info == {}:
            return converted[2]

        return self.convert_reference_relpaths(converted[2])

    def convert_attributes_if_needed(self, tag, attrs):
        converted = self.get_starttag_text()
        if self.convert_test_harness_links and tag in ('script', 'link'):
            attr_name = 'src'
            if tag != 'script':
                attr_name = 'href'
            for attr in attrs:
                if attr[0] == attr_name:
                    new_path = re.sub(self.test_harness_re, self.new_test_harness_path + '/testharness', attr[1])
                    converted = re.sub(re.escape(attr[1]), new_path, converted)

        for attr in attrs:
            if attr[0] == 'style':
                new_style = self.convert_style_data(attr[1])
                converted = re.sub(re.escape(attr[1]), new_style, converted)

        # Convert relative paths
        src_tags = ('script', 'style', 'img', 'frame', 'iframe', 'input', 'layer', 'textarea', 'video', 'audio')
        if self.reference_support_info is not None and self.reference_support_info != {}:
            if tag in src_tags:
                for attr_name, attr_value in attrs:
                    if attr_name == 'src':
                        new_path = self.convert_reference_relpaths(attr_value)
                        converted = re.sub(re.escape(attr_value), new_path, converted)
            if tag == 'link':
                for attr_name, attr_value in attrs:
                    if attr_name == 'href':
                        new_path = self.convert_reference_relpaths(attr_value)
                        converted = re.sub(re.escape(attr_value), new_path, converted)
        self.converted_data.append(converted)

    def add_webkit_test_runner_options_if_needed(self):
        if self.has_started:
            return
        self.has_started = True
        if self.webkit_test_runner_options:
            self.converted_data[-1] = self.converted_data[-1] + self.webkit_test_runner_options

    def handle_starttag(self, tag, attrs):
        if tag == 'style':
            self.in_style_tag = True
        self.convert_attributes_if_needed(tag, attrs)
        self.add_webkit_test_runner_options_if_needed()

    def handle_endtag(self, tag):
        if tag == 'style':
            self.converted_data.append(self.convert_style_data(''.join(self.style_data)))
            self.in_style_tag = False
            self.style_data = []
        self.converted_data.extend(['</', tag, '>'])

    def handle_startendtag(self, tag, attrs):
        self.convert_attributes_if_needed(tag, attrs)

    def handle_data(self, data):
        if self.in_style_tag:
            self.style_data.append(data)
        else:
            self.converted_data.append(data)

    def handle_entityref(self, name):
        self.converted_data.extend(['&', name, ';'])

    def handle_charref(self, name):
        self.converted_data.extend(['&#', name, ';'])

    def handle_comment(self, data):
        self.converted_data.extend(['<!--', data, '-->'])
        self.add_webkit_test_runner_options_if_needed()

    def handle_decl(self, decl):
        self.converted_data.extend(['<!', decl, '>'])
        self.add_webkit_test_runner_options_if_needed()

    def handle_pi(self, data):
        self.converted_data.extend(['<?', data, '>'])
        self.add_webkit_test_runner_options_if_needed()
