#!/usr/bin/env python3
# Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import json
import os.path
import re
import sys

_COMPAT_KEY = '__compat'
_EXPERIMENTAL_KEY = 'experimental'
_STATUS_KEY = 'status'
_SUPPORT_KEY = 'support'
_VERSION_ADDED_KEY = 'version_added'


def _get_browser_compat_data():
    current_dir = os.path.dirname(__file__)

    browser_compat_folder = os.path.abspath(
        os.path.join(current_dir, '..', '..', '..', 'third_party', 'mdn',
                     'browser-compat-data', 'src'))

    if not os.path.exists(browser_compat_folder):
        raise RuntimeError('Browser compatibility data not found at %s' %
                           browser_compat_folder)

    browser_compat_data = {}

    INCLUDE_DIRS = [
        'api',
        'html',
        'svg',
        # TODO(srujzs): add more if needed
    ]

    # Transform to absolute paths
    INCLUDE_DIRS = [
        os.path.join(browser_compat_folder, dir) for dir in INCLUDE_DIRS
    ]

    def process_json_dict(json_dict):
        # Returns a tuple of the interface name and the metadata corresponding
        # to it.
        if 'api' in json_dict:
            # Get the interface name
            api_dict = json_dict['api']
            interface_name = next(iter(api_dict))
            return (interface_name, api_dict[interface_name])
        elif 'html' in json_dict:
            html_dict = json_dict['html']
            if 'elements' in html_dict:
                elements_dict = html_dict['elements']
                element_name = next(iter(elements_dict))
                # Convert to WebCore name
                interface = str('HTML' + element_name + 'Element')
                return (interface, elements_dict[element_name])
        elif 'svg' in json_dict:
            svg_dict = json_dict['svg']
            if 'elements' in svg_dict:
                elements_dict = svg_dict['elements']
                element_name = next(iter(elements_dict))
                # Convert to WebCore name
                interface = str('SVG' + element_name + 'Element')
                return (interface, elements_dict[element_name])
        return (None, None)

    # Attempts to unify two compatibility infos by taking the union of both, and
    # for conflicting information, taking the "stricter" of the two versions.
    # Updates `a` in place to represent the union of `a` and `b`.
    def _unify_compat(a, b):

        def _has_compat_data(metadata):
            return _COMPAT_KEY in metadata and _SUPPORT_KEY in metadata[_COMPAT_KEY]

        # Unifies the support statements of both metadata and updates
        # `support_a` in place. If either metadata do not contain simple support
        # statements, defaults attribute to not supported.
        def _unify_support(support_a, support_b):
            for browser in support_a.keys():
                if browser in support_b:
                    if _is_simple_support_statement(support_a[browser]) and _is_simple_support_statement(support_b[browser]):
                        support_a[browser][_VERSION_ADDED_KEY] = _unify_versions(
                            support_a[browser][_VERSION_ADDED_KEY],
                            support_b[browser][_VERSION_ADDED_KEY])
                    else:
                        # Only support simple statements for now.
                        support_a[browser] = {_VERSION_ADDED_KEY: None}
            for browser in support_b.keys():
                if not browser in support_a:
                    support_a[browser] = support_b[browser]

        if not _has_compat_data(b):
            return
        if not _has_compat_data(a):
            a[_COMPAT_KEY] = b[_COMPAT_KEY]
            return

        support_a = a[_COMPAT_KEY][_SUPPORT_KEY]
        support_b = b[_COMPAT_KEY][_SUPPORT_KEY]

        _unify_support(support_a, support_b)

    # Unifies any status info in the two metadata. Modifies `a` in place to
    # represent the union of both `a` and `b`.
    def _unify_status(a, b):

        def _has_status(metadata):
            return _COMPAT_KEY in metadata and _STATUS_KEY in metadata[_COMPAT_KEY]

        # Modifies `status_a` in place to combine "experimental" tags.
        def _unify_experimental(status_a, status_b):
            # If either of the statuses report experimental, assume attribute is
            # experimental.
            status_a[_EXPERIMENTAL_KEY] = status_a.get(
                _EXPERIMENTAL_KEY, False) or status_b.get(_EXPERIMENTAL_KEY, False)

        if not _has_status(b):
            return
        if not _has_status(a):
            a[_COMPAT_KEY] = b[_COMPAT_KEY]
            return

        status_a = a[_COMPAT_KEY][_STATUS_KEY]
        status_b = b[_COMPAT_KEY][_STATUS_KEY]

        _unify_experimental(status_a, status_b)

    # If there exists multiple definitions of the same interface metadata e.g.
    # elements, this attempts to unify the compatibilities for the interface as
    # well as for each attribute.
    def _unify_metadata(a, b):
        # Unify the compatibility statement and status of the API or element.
        _unify_compat(a, b)
        _unify_status(a, b)
        # Unify the compatibility statement and status of each attribute.
        for attr in list(a.keys()):
            if attr == _COMPAT_KEY:
                continue
            if attr in b:
                _unify_compat(a[attr], b[attr])
                _unify_status(a[attr], b[attr])
        for attr in b.keys():
            if not attr in a:
                a[attr] = b[attr]

    for (dir_path, dirs, files) in os.walk(browser_compat_folder):

        def should_process_dir(dir_path):
            if os.path.abspath(dir_path) == browser_compat_folder:
                return True
            for dir in INCLUDE_DIRS:
                if dir_path.startswith(dir):
                    return True
            return False

        if should_process_dir(dir_path):
            for name in files:
                file_name = os.path.join(dir_path, name)
                (interface_path, ext) = os.path.splitext(file_name)
                if ext == '.json':
                    with open(file_name) as src:
                        json_dict = json.load(src)
                        interface, metadata = process_json_dict(json_dict)
                        if not interface is None:
                            # Note: interface and member names do not
                            # necessarily have the same capitalization as
                            # WebCore, so we keep them all lowercase for easier
                            # matching later.
                            interface = interface.lower()
                            metadata = {
                                member.lower(): info
                                for member, info in metadata.items()
                            }

                            if interface in browser_compat_data:
                                _unify_metadata(browser_compat_data[interface],
                                                metadata)
                            else:
                                browser_compat_data[interface] = metadata
        else:
            dirs[:] = []  # Do not go underneath

    return browser_compat_data


# Given two version values for a given browser, chooses the more strict version.
def _unify_versions(version_a, version_b):
    # Given two valid version strings, compares parts of the version string
    # iteratively.
    def _greater_version(version_a, version_b):
        version_a_split = list(map(int, version_a.split('.')))
        version_b_split = list(map(int, version_b.split('.')))
        for i in range(min(len(version_a_split), len(version_b_split))):
            if version_a_split[i] > version_b_split[i]:
                return version_a
            elif version_a_split[i] < version_b_split[i]:
                return version_b
        return version_a if len(version_a_split) > len(
            version_b_split) else version_b

    # Validate that we can handle the given version.
    def _validate_version(version):
        if not version:
            return False
        if version is True:
            return True
        if isinstance(version, str):
            pattern = re.compile('^([0-9]+\.)*[0-9]+$')
            if not pattern.match(version):
                # It's possible for version strings to look like '<35'. We don't
                # attempt to parse the conditional logic, and just default to
                # potentially incompatible.
                return None
            return version
        else:
            raise ValueError(
                'Type of version_a was not handled correctly! type(version) = '
                + str(type(version)))

    version_a = _validate_version(version_a)
    version_b = _validate_version(version_b)
    # If one version reports not supported, default to not supported.
    if not version_a or not version_b:
        return False
    # If one version reports always supported, the other version can only be
    # more strict.
    if version_a is True:
        return version_b
    if version_b is True:
        return version_a

    return _greater_version(version_a, version_b)


# At this time, we only handle simple support statements due to the complexity
# and variability around support statements with multiple elements.
def _is_simple_support_statement(support_statement):
    if isinstance(support_statement, list):  # array_support_statement
        # TODO(srujzs): Parse this list to determine compatibility. Will
        # likely require parsing for 'version_removed' keys. Notes about
        # which browser version enabled this attribute for which
        # platform also complicates things. For now, we assume it's not
        # compatible.
        return False
    if len(support_statement.keys()) > 1:
        # If it's anything more complicated than 'version_added', like
        # 'notes' that specify platform versions, we assume it's not
        # compatible.
        return False
    return True


class MDNReader(object):
    # Statically initialize and treat as constant.
    _BROWSER_COMPAT_DATA = _get_browser_compat_data()

    def __init__(self):
        self._compat_overrides = {}

    def _get_attr_compatibility(self, compat_data):
        # Parse schema syntax of MDN data:
        # https://github.com/mdn/browser-compat-data/blob/master/schemas/compat-data.schema.json

        # For now, we will require support for browsers since the last IDL roll.
        # TODO(srujzs): Determine if this is too conservative.
        browser_version_map = {
            'chrome': '63',
            'firefox': '57',
            'safari': '11',
            # We still support the latest version of IE.
            'ie': '11',
            'opera': '50',
        }
        for browser in browser_version_map.keys():
            support_data = compat_data[_SUPPORT_KEY]
            if browser not in support_data:
                return False
            support_statement = support_data[browser]
            if not _is_simple_support_statement(support_statement):
                return False
            version = support_statement[_VERSION_ADDED_KEY]
            # Compare version strings, target should be the more strict version.
            target = browser_version_map[browser]
            if _unify_versions(version, target) != target:
                return False

            # If the attribute is experimental, we assume it's not compatible.
            status_data = compat_data[_STATUS_KEY]
            if _EXPERIMENTAL_KEY in status_data and status_data[_EXPERIMENTAL_KEY]:
                return False
        return True

    def is_compatible(self, attribute):
        # Since capitalization isn't consistent across MDN and WebCore, we
        # compare lowercase equivalents for interface and attribute names.
        interface = attribute.doc_js_interface_name.lower()
        if interface in self._BROWSER_COMPAT_DATA and attribute.id and len(
                attribute.id) > 0:
            interface_dict = self._BROWSER_COMPAT_DATA[interface]
            id_name = attribute.id.lower()
            secure_context_key = 'isSecureContext'
            if interface in self._compat_overrides and id_name in self._compat_overrides[
                    interface]:
                return self._compat_overrides[interface][id_name]
            elif secure_context_key in interface_dict:
                # If the interface requires a secure context, all attributes are
                # implicitly incompatible.
                return False
            elif id_name in interface_dict:
                id_data = interface_dict[id_name]
                return self._get_attr_compatibility(id_data[_COMPAT_KEY])
            else:
                # Might be an attribute that is defined in a parent interface.
                # We defer until attribute emitting to determine if this is the
                # case. Otherwise, return None.
                pass
        return None

    def set_compatible(self, attribute, compatible):
        # Override value in the MDN browser compatibility data.
        if not compatible in [True, False, None]:
            raise ValueError('Cannot set a non-boolean object for compatible')
        interface = attribute.doc_js_interface_name.lower()
        if not interface in self._compat_overrides:
            self._compat_overrides[interface] = {}
        if attribute.id and len(attribute.id) > 0:
            id_name = attribute.id.lower()
            self._compat_overrides[interface][id_name] = compatible
