# Copyright 2019 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 web_idl

_CODE_GEN_EXPR_PASS_KEY = object()


class CodeGenExpr(object):
    """
    Represents an expression which is composable to produce another expression.

    This is designed primarily to represent conditional expressions and basic
    logical operators (expr_not, expr_and, expr_or) come along with.
    """

    def __init__(self, expr, is_compound=False, pass_key=None):
        assert isinstance(expr, (bool, str))
        assert isinstance(is_compound, bool)
        assert pass_key is _CODE_GEN_EXPR_PASS_KEY

        if isinstance(expr, bool):
            self._text = "true" if expr else "false"
        else:
            self._text = expr
        self._is_compound = is_compound
        self._is_always_false = expr is False
        self._is_always_true = expr is True

    def __eq__(self, other):
        if not isinstance(self, other.__class__):
            return NotImplemented
        # Assume that, as long as the two texts are the same, the two
        # expressions must be the same, i.e. |_is_compound|, etc. must be the
        # same or do not matter.
        return self.to_text() == other.to_text()

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash(self.to_text())

    def __str__(self):
        """
        __str__ is designed to be used when composing another expression.  If
        you'd only like to have a string representation, |to_text| works better.
        """
        if self._is_compound:
            return "({})".format(self.to_text())
        return self.to_text()

    def to_text(self):
        return self._text

    @property
    def is_always_false(self):
        """
        The expression is always False, and code generators have chances of
        optimizations.
        """
        return self._is_always_false

    @property
    def is_always_true(self):
        """
        The expression is always True, and code generators have chances of
        optimizations.
        """
        return self._is_always_true


def _Expr(*args, **kwargs):
    return CodeGenExpr(*args, pass_key=_CODE_GEN_EXPR_PASS_KEY, **kwargs)


def _unary_op(op, term):
    assert isinstance(op, str)
    assert isinstance(term, CodeGenExpr)

    return _Expr("{}{}".format(op, term), is_compound=True)


def _binary_op(op, terms):
    assert isinstance(op, str)
    assert isinstance(terms, (list, tuple))
    assert all(isinstance(term, CodeGenExpr) for term in terms)
    assert all(
        not (term.is_always_false or term.is_always_true) for term in terms)

    return _Expr(op.join(map(str, terms)), is_compound=True)


def expr_not(term):
    assert isinstance(term, CodeGenExpr)

    if term.is_always_false:
        return _Expr(True)
    if term.is_always_true:
        return _Expr(False)
    return _unary_op("!", term)


def expr_and(terms):
    assert isinstance(terms, (list, tuple))
    assert all(isinstance(term, CodeGenExpr) for term in terms)
    assert terms

    if any(term.is_always_false for term in terms):
        return _Expr(False)
    terms = list(filter(lambda x: not x.is_always_true, terms))
    if not terms:
        return _Expr(True)
    if len(terms) == 1:
        return terms[0]
    return _binary_op(" && ", expr_uniq(terms))


def expr_or(terms):
    assert isinstance(terms, (list, tuple))
    assert all(isinstance(term, CodeGenExpr) for term in terms)
    assert terms

    if any(term.is_always_true for term in terms):
        return _Expr(True)
    terms = list(filter(lambda x: not x.is_always_false, terms))
    if not terms:
        return _Expr(False)
    if len(terms) == 1:
        return terms[0]
    return _binary_op(" || ", expr_uniq(terms))


def expr_uniq(terms):
    assert isinstance(terms, (list, tuple))
    assert all(isinstance(term, CodeGenExpr) for term in terms)

    uniq_terms = []
    for term in terms:
        if term not in uniq_terms:
            uniq_terms.append(term)
    return uniq_terms


def expr_from_exposure(exposure,
                       global_names=None,
                       may_use_feature_selector=False):
    """
    Returns an expression to determine whether this property should be exposed
    or not.

    Args:
        exposure: web_idl.Exposure of the target construct.
        global_names: When specified, it's taken into account that the global
            object implements |global_names|.
        may_use_feature_selector: True enables use of ${feature_selector} iff
            the exposure is context dependent.
    """
    assert isinstance(exposure, web_idl.Exposure)
    assert (global_names is None
            or (isinstance(global_names, (list, tuple))
                and all(isinstance(name, str) for name in global_names)))

    # The property exposures are categorized into three.
    # - Unconditional: Always exposed.
    # - Context-independent: Enabled per v8::Isolate.
    # - Context-dependent: Enabled per v8::Context, e.g. origin trials.
    #
    # Context-dependent properties can be installed in two phases.
    # - The first phase installs all the properties that are associated with the
    #   features enabled at the moment.  This phase is represented by
    #   FeatureSelector as FeatureSelector.IsAll().
    # - The second phase installs the properties associated with the specified
    #   feature.  This phase is represented as FeatureSelector.IsAny(feature).
    #
    # The exposure condition is represented as;
    #   (and feature_selector-independent-term
    #        (or
    #         feature_selector-1st-phase-term
    #         feature_selector-2nd-phase-term))
    # which can be represented in more details as:
    #   (and secure_context_term
    #        uncond_exposed_term
    #        (or
    #         (and feature_selector.IsAll()  # 1st phase; all enabled
    #              cond_exposed_term
    #              (or feature_enabled_term
    #                  context_enabled_term))
    #         (or exposed_selector_term      # 2nd phase; any selected
    #             feature_selector_term)))
    # where
    #   secure_context_term represents [SecureContext=F1]
    #   uncond_exposed_term represents [Exposed=(G1, G2)]
    #   cond_exposed_term represents [Exposed(G1 F1, G2 F2)]
    #   feature_enabled_term represents [RuntimeEnabled=(F1, F2)]
    #   context_enabled_term represents [ContextEnabled=F1]
    #   exposed_selector_term represents [Exposed(G1 F1, G2 F2)]
    #   feature_selector_term represents [RuntimeEnabled=(F1, F2)]
    uncond_exposed_terms = []
    cond_exposed_terms = []
    feature_enabled_terms = []
    context_enabled_terms = []
    exposed_selector_terms = []
    feature_selector_names = []  # Will turn into feature_selector.IsAnyOf(...)

    def ref_enabled(feature):
        arg = "${execution_context}" if feature.is_context_dependent else ""
        return _Expr("RuntimeEnabledFeatures::{}Enabled({})".format(
            feature, arg))

    def ref_selected(features):
        feature_tokens = map(
            lambda feature: "OriginTrialFeature::k{}".format(feature),
            features)
        return _Expr("${{feature_selector}}.IsAnyOf({})".format(
            ", ".join(feature_tokens)))

    # [SecureContext]
    if exposure.only_in_secure_contexts is True:
        secure_context_term = _Expr("${is_in_secure_context}")
    elif exposure.only_in_secure_contexts is False:
        secure_context_term = _Expr(True)
    else:
        terms = list(map(ref_enabled, exposure.only_in_secure_contexts))
        secure_context_term = expr_or(
            [_Expr("${is_in_secure_context}"),
             expr_not(expr_and(terms))])

    # [Exposed]
    GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST = {
        "AnimationWorklet": "IsAnimationWorkletGlobalScope",
        "AudioWorklet": "IsAudioWorkletGlobalScope",
        "DedicatedWorker": "IsDedicatedWorkerGlobalScope",
        "LayoutWorklet": "IsLayoutWorkletGlobalScope",
        "PaintWorklet": "IsPaintWorkletGlobalScope",
        "ServiceWorker": "IsServiceWorkerGlobalScope",
        "SharedWorker": "IsSharedWorkerGlobalScope",
        "Window": "IsWindow",
        "Worker": "IsWorkerGlobalScope",
        "Worklet": "IsWorkletGlobalScope",
    }
    if global_names:
        matched_global_count = 0
        for entry in exposure.global_names_and_features:
            if entry.global_name not in global_names:
                continue
            matched_global_count += 1
            if entry.feature:
                cond_exposed_terms.append(ref_enabled(entry.feature))
                if entry.feature.is_context_dependent:
                    feature_selector_names.append(entry.feature)
        assert (not exposure.global_names_and_features
                or matched_global_count > 0)
    else:
        for entry in exposure.global_names_and_features:
            pred_term = _Expr("${{execution_context}}->{}()".format(
                GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name]))
            if not entry.feature:
                uncond_exposed_terms.append(pred_term)
            else:
                cond_exposed_terms.append(
                    expr_and([pred_term, ref_enabled(entry.feature)]))
                if entry.feature.is_context_dependent:
                    exposed_selector_terms.append(
                        expr_and([pred_term,
                                  ref_selected([entry.feature])]))

    # [RuntimeEnabled]
    if exposure.runtime_enabled_features:
        feature_enabled_terms.extend(
            map(ref_enabled, exposure.runtime_enabled_features))
        feature_selector_names.extend(
            exposure.context_dependent_runtime_enabled_features)

    # [ContextEnabled]
    if exposure.context_enabled_features:
        terms = list(
            map(
                lambda feature: _Expr(
                    "${{context_feature_settings}}->is{}Enabled()".format(
                        feature)), exposure.context_enabled_features))
        context_enabled_terms.append(
            expr_and([_Expr("${context_feature_settings}"),
                      expr_or(terms)]))

    # Build an expression.
    top_level_terms = []
    top_level_terms.append(secure_context_term)
    if uncond_exposed_terms:
        top_level_terms.append(expr_or(uncond_exposed_terms))

    if not (may_use_feature_selector
            and exposure.is_context_dependent(global_names)):
        if cond_exposed_terms:
            top_level_terms.append(expr_or(cond_exposed_terms))
        if feature_enabled_terms:
            top_level_terms.append(expr_and(feature_enabled_terms))
        return expr_and(top_level_terms)

    all_enabled_terms = [_Expr("${feature_selector}.IsAll()")]
    if cond_exposed_terms:
        all_enabled_terms.append(expr_or(cond_exposed_terms))
    if feature_enabled_terms or context_enabled_terms:
        terms = []
        if feature_enabled_terms:
            terms.append(expr_and(feature_enabled_terms))
        if context_enabled_terms:
            terms.append(expr_or(context_enabled_terms))
        all_enabled_terms.append(expr_or(terms))

    selector_terms = []
    if exposed_selector_terms:
        selector_terms.append(expr_or(exposed_selector_terms))
    if feature_selector_names:
        selector_terms.append(ref_selected(feature_selector_names))

    terms = []
    terms.append(expr_and(all_enabled_terms))
    if selector_terms:
        terms.append(expr_or(selector_terms))
    top_level_terms.append(expr_or(terms))

    return expr_and(top_level_terms)
