# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

# fmt: off

from __future__ import annotations

import os
import sys
import json
import re
from typing import TYPE_CHECKING
from collections.abc import Iterator

SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
SERVO_ROOT = os.path.abspath(os.path.join(SCRIPT_PATH, "..", "..", ".."))

FILTER_PATTERN = re.compile("// skip-unless ([A-Z_]+)\n")

if TYPE_CHECKING:
    from configuration import Configuration
    from WebIDL import Parser

def main() -> None:
    os.chdir(os.path.join(os.path.dirname(__file__)))
    sys.path.insert(0, os.path.join(SERVO_ROOT, "third_party", "WebIDL"))
    sys.path.insert(0, os.path.join(SERVO_ROOT, "third_party", "ply"))

    css_properties_json, out_dir = sys.argv[1:]
    # Four dotdots: /path/to/target(4)/debug(3)/build(2)/style-*(1)/out
    # Do not ascend above the target dir, because it may not be called target
    # or even have a parent (see CARGO_TARGET_DIR).
    doc_servo = os.path.join(out_dir, "..", "..", "..", "..", "doc")
    webidls_dir = os.path.join(SCRIPT_PATH, "..", "webidls")
    config_file = "Bindings.conf"

    import WebIDL
    from configuration import Configuration
    from codegen import CGBindingRoot, CGConcreteBindingRoot

    parser = WebIDL.Parser(make_dir(os.path.join(out_dir, "cache")))
    webidls = [name for name in os.listdir(webidls_dir) if name.endswith(".webidl")]
    for webidl in webidls:
        filename = os.path.join(webidls_dir, webidl)
        with open(filename, "r", encoding="utf-8") as f:
            contents = f.read()
            filter_match = FILTER_PATTERN.search(contents)
            if filter_match:
                env_var = filter_match.group(1)
                if not os.environ.get(env_var):
                    continue

            parser.parse(contents, filename)

    add_css_properties_attributes(css_properties_json, parser)
    parser_results = parser.finish()
    config = Configuration(config_file, parser_results)
    make_dir(os.path.join(out_dir, "Bindings"))
    make_dir(os.path.join(out_dir, "ConcreteBindings"))

    for name, filename in [
        ("PrototypeList", "PrototypeList.rs"),
        ("RegisterBindings", "RegisterBindings.rs"),
        ("Globals", "Globals.rs"),
        ("InterfaceObjectMap", "InterfaceObjectMap.rs"),
        ("InterfaceObjectMapData", "InterfaceObjectMapData.json"),
        ("InterfaceTypes", "InterfaceTypes.rs"),
        ("InheritTypes", "InheritTypes.rs"),
        ("ConcreteInheritTypes", "ConcreteInheritTypes.rs"),
        ("Bindings", "Bindings/mod.rs"),
        ("Bindings", "ConcreteBindings/mod.rs"),
        ("UnionTypes", "GenericUnionTypes.rs"),
        ("ConcreteUnionTypes", "UnionTypes.rs"),
        ("DomTypes", "DomTypes.rs"),
        ("DomTypeHolder", "DomTypeHolder.rs"),
    ]:
        generate(config, name, os.path.join(out_dir, filename))
    make_dir(doc_servo)
    generate(config, "SupportedDomApis", os.path.join(doc_servo, "apis.html"))

    for webidl in webidls:
        filename = os.path.join(webidls_dir, webidl)
        prefix = "Bindings/%sBinding" % webidl[:-len(".webidl")]
        module = CGBindingRoot(config, prefix, filename).define()
        if module:
            with open(os.path.join(out_dir, prefix + ".rs"), "wb") as f:
                f.write(module.encode("utf-8"))
        prefix = "ConcreteBindings/%sBinding" % webidl[:-len(".webidl")]
        module = CGConcreteBindingRoot(config, prefix, filename).define()
        if module:
            with open(os.path.join(out_dir, prefix + ".rs"), "wb") as f:
                f.write(module.encode("utf-8"))


def make_dir(path: str)-> str:
    if not os.path.exists(path):
        os.makedirs(path)
    return path


def generate(config: Configuration, name: str, filename: str) -> None:
    from codegen import GlobalGenRoots
    root = getattr(GlobalGenRoots, name)(config)
    code = root.define()
    with open(filename, "wb") as f:
        f.write(code.encode("utf-8"))


def add_css_properties_attributes(css_properties_json: str, parser: Parser) -> None:
    def map_preference_name(preference_name: str) -> str:
        """Map between Stylo preference names and Servo preference names as the
        `css-properties.json` file is generated by Stylo. This should be kept in sync with the
        preference mapping done in `components/servo_config/prefs.rs`, which handles the runtime version of
        these preferences."""
        MAPPING = [
            ["layout.unimplemented", "layout_unimplemented"],
            ["layout.threads", "layout_threads"],
            ["layout.flexbox.enabled", "layout_flexbox_enabled"],
            ["layout.columns.enabled", "layout_columns_enabled"],
            ["layout.grid.enabled", "layout_grid_enabled"],
            ["layout.css.transition-behavior.enabled", "layout_css_transition_behavior_enabled"],
            ["layout.writing-mode.enabled", "layout_writing_mode_enabled"],
            ["layout.container-queries.enabled", "layout_container_queries_enabled"],
            ["layout.variable_fonts.enabled", "layout_variable_fonts_enabled"]
        ]
        for mapping in MAPPING:
            if mapping[0] == preference_name:
                return mapping[1]
        return preference_name

    css_properties = json.load(open(css_properties_json, "rb"))
    idl = "partial interface CSSStyleDeclaration {\n%s\n};\n" % "\n".join(
        "  [%sCEReactions, SetterThrows] attribute [LegacyNullToEmptyString] DOMString %s;" % (
            (f'Pref="{map_preference_name(data["pref"])}", ' if data["pref"] else ""),
            attribute_name
        )
        for (kind, properties_list) in sorted(css_properties.items())
        for (property_name, data) in sorted(properties_list.items())
        for attribute_name in attribute_names(property_name)
    )
    parser.parse(idl, "CSSStyleDeclaration_generated.webidl")


def attribute_names(property_name: str) -> Iterator[str]:
    # https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-dashed-attribute
    if property_name != "float":
        yield property_name
    else:
        yield "_float"

    # https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-camel-cased-attribute
    if "-" in property_name:
        yield "".join(camel_case(property_name))

    # https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-webkit-cased-attribute
    if property_name.startswith("-webkit-"):
        yield "".join(camel_case(property_name, True))


# https://drafts.csswg.org/cssom/#css-property-to-idl-attribute
def camel_case(chars: str, webkit_prefixed: bool = False) -> Iterator[str]:
    if webkit_prefixed:
        chars = chars[1:]
    next_is_uppercase = False
    for c in chars:
        if c == '-':
            next_is_uppercase = True
        elif next_is_uppercase:
            next_is_uppercase = False
            # Should be ASCII-uppercase, but all non-custom CSS property names are within ASCII
            yield c.upper()
        else:
            yield c


if __name__ == "__main__":
    main()
