# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("//build/make/core:envsetup.rbc", _envsetup_init = "init")

"""Runtime functions."""

def _global_init():
    """Returns dict created from the runtime environment."""
    globals = dict()

    # Environment variables
    for k in dir(rblf_env):
        globals[k] = getattr(rblf_env, k)

    # Variables set as var=value command line arguments
    for k in dir(rblf_cli):
        globals[k] = getattr(rblf_cli, k)

    globals.setdefault("PRODUCT_SOONG_NAMESPACES", [])
    _envsetup_init(globals)

    # Variables that should be defined.
    mandatory_vars = [
        "PLATFORM_VERSION_CODENAME",
        "PLATFORM_VERSION",
        "PRODUCT_SOONG_NAMESPACES",
        # TODO(asmundak): do we need TARGET_ARCH? AOSP does not reference it
        "TARGET_BUILD_TYPE",
        "TARGET_BUILD_VARIANT",
        "TARGET_PRODUCT",
    ]
    for bv in mandatory_vars:
        if not bv in globals:
            fail(bv, " is not defined")

    return globals

_globals_base = _global_init()

def __print_attr(attr, value):
    if not value:
        return
    if type(value) == "list":
        if _options.rearrange:
            value = __printvars_rearrange_list(value)
        if _options.format == "pretty":
            print(attr, "=", repr(value))
        elif _options.format == "make":
            print(attr, ":=", " ".join(value))
    elif _options.format == "pretty":
        print(attr, "=", repr(value))
    elif _options.format == "make":
        print(attr, ":=", value)
    else:
        fail("bad output format", _options.format)

def _printvars(globals, cfg):
    """Prints known configuration variables."""
    for attr, val in sorted(cfg.items()):
        __print_attr(attr, val)
    if _options.print_globals:
        print()
        for attr, val in sorted(globals.items()):
            if attr not in _globals_base:
                __print_attr(attr, val)

def __printvars_rearrange_list(value_list):
    """Rearrange value list: return only distinct elements, maybe sorted."""
    seen = {item: 0 for item in value_list}
    return sorted(seen.keys()) if _options.rearrange == "sort" else seen.keys()

def _product_configuration(top_pcm_name, top_pcm):
    """Creates configuration."""

    # Product configuration is created by traversing product's inheritance
    # tree. It is traversed twice.
    # First, beginning with top-level module we execute a module and find
    # its ancestors, repeating this recursively. At the end of this phase
    # we get the full inheritance tree.
    # Second, we traverse the tree in the postfix order (i.e., visiting a
    # node after its ancestors) to calculate the product configuration.
    #
    # PCM means "Product Configuration Module", i.e., a Starlark file
    # whose body consists of a single init function.

    globals = dict(**_globals_base)

    config_postfix = []  # Configs in postfix order

    # Each PCM is represented by a quadruple of function, config, children names
    # and readyness (that is, the configurations from inherited PCMs have been
    # substituted).
    configs = {top_pcm_name: (top_pcm, None, [], False)}  # All known PCMs

    stash = []  # Configs to push once their descendants are done

    # Stack containing PCMs to be processed. An item in the stack
    # is a pair of PCMs name and its height in the product inheritance tree.
    pcm_stack = [(top_pcm_name, 0)]
    pcm_count = 0

    # Run it until pcm_stack is exhausted, but no more than N times
    for n in range(1000):
        if not pcm_stack:
            break
        (name, height) = pcm_stack.pop()
        pcm, cfg, c, _ = configs[name]

        # cfg is set only after PCM has been called, leverage this
        # to prevent calling the same PCM twice
        if cfg != None:
            continue

        # Push ancestors until we reach this node's height
        config_postfix.extend([stash.pop() for i in range(len(stash) - height)])

        # Run this one, obtaining its configuration and child PCMs.
        if _options.trace_modules:
            print("%d:" % n)

        # Run PCM.
        handle = __h_new()
        pcm(globals, handle)

        # Now we know everything about this PCM, record it in 'configs'.
        children = __h_inherited_modules(handle)
        if _options.trace_modules:
            print("   ", "    ".join(children.keys()))
        configs[name] = (pcm, __h_cfg(handle), children.keys(), False)
        pcm_count = pcm_count + 1

        if len(children) == 0:
            # Leaf PCM goes straight to the config_postfix
            config_postfix.append(name)
            continue

        # Stash this PCM, process children in the sorted order
        stash.append(name)
        for child_name in sorted(children, reverse = True):
            if child_name not in configs:
                configs[child_name] = (children[child_name], None, [], False)
            pcm_stack.append((child_name, len(stash)))
    if pcm_stack:
        fail("Inheritance processing took too many iterations")

    # Flush the stash
    config_postfix.extend([stash.pop() for i in range(len(stash))])
    if len(config_postfix) != pcm_count:
        fail("Ran %d modules but postfix tree has only %d entries" % (pcm_count, len(config_postfix)))

    if _options.trace_modules:
        print("\n---Postfix---")
        for x in config_postfix:
            print("   ", x)

    # Traverse the tree from the bottom, evaluating inherited values
    for pcm_name in config_postfix:
        pcm, cfg, children_names, ready = configs[pcm_name]

        # Should run
        if cfg == None:
            fail("%s: has not been run" % pcm_name)

        # Ready once
        if ready:
            continue

        # Children should be ready
        for child_name in children_names:
            if not configs[child_name][3]:
                fail("%s: child is not ready" % child_name)

        _substitute_inherited(configs, pcm_name, cfg)
        _percolate_inherited(configs, pcm_name, cfg, children_names)
        configs[pcm_name] = pcm, cfg, children_names, True

    return globals, configs[top_pcm_name][1]

def _substitute_inherited(configs, pcm_name, cfg):
    """Substitutes inherited values in all the attributes.

    When a value of an attribute is a list, some of its items may be
    references to a value of a same attribute in an inherited product,
    e.g., for a given module PRODUCT_PACKAGES can be
      ["foo", (submodule), "bar"]
    and for 'submodule' PRODUCT_PACKAGES may be ["baz"]
    (we use a tuple to distinguish submodule references).
    After the substitution the value of PRODUCT_PACKAGES for the module
    will become ["foo", "baz", "bar"]
    """
    for attr, val in cfg.items():
        # TODO(asmundak): should we handle single vars?
        if type(val) != "list":
            continue

        if attr not in _options.trace_variables:
            cfg[attr] = _value_expand(configs, attr, val)
        else:
            old_val = val
            new_val = _value_expand(configs, attr, val)
            if new_val != old_val:
                print("%s(i): %s=%s (was %s)" % (pcm_name, attr, new_val, old_val))
            cfg[attr] = new_val

def _value_expand(configs, attr, values_list):
    """Expands references to inherited values in a given list."""
    result = []
    expanded = {}
    for item in values_list:
        # Inherited values are 1-tuples
        if type(item) != "tuple":
            result.append(item)
            continue
        child_name = item[0]
        if child_name in expanded:
            continue
        expanded[child_name] = True
        child = configs[child_name]
        if not child[3]:
            fail("%s should be ready" % child_name)
        __move_items(result, child[1], attr)

    return result

def _percolate_inherited(configs, cfg_name, cfg, children_names):
    """Percolates the settings that are present only in children."""
    percolated_attrs = {}
    for child_name in children_names:
        child_cfg = configs[child_name][1]
        for attr, value in child_cfg.items():
            if type(value) != "list":
                if attr in percolated_attrs or not attr in cfg:
                    cfg[attr] = value
                    percolated_attrs[attr] = True
                continue
            if attr in percolated_attrs:
                # We already are percolating this one, just add this list
                __move_items(cfg[attr], child_cfg, attr)
            elif not attr in cfg:
                percolated_attrs[attr] = True
                cfg[attr] = []
                __move_items(cfg[attr], child_cfg, attr)

    for attr in _options.trace_variables:
        if attr in percolated_attrs:
            print("%s: %s^=%s" % (cfg_name, attr, cfg[attr]))

def __move_items(to_list, from_cfg, attr):
    value = from_cfg.get(attr, [])
    if value:
        to_list.extend(value)
        from_cfg[attr] = []

def _indirect(pcm_name):
    """Returns configuration item for the inherited module."""
    return (pcm_name,)

def _addprefix(prefix, string_or_list):
    """Adds prefix and returns a list.

    If string_or_list is a list, prepends prefix to each element.
    Otherwise, string_or_list is considered to be a string which
    is split into words and then prefix is prepended to each one.

    Args:
        prefix
        string_or_list

    """
    return [prefix + x for x in __words(string_or_list)]

def _addsuffix(suffix, string_or_list):
    """Adds suffix and returns a list.

    If string_or_list is a list, appends suffix to each element.
    Otherwise, string_or_list is considered to be a string which
    is split into words and then suffix is appended to each one.

    Args:
      suffix
      string_or_list
    """
    return [x + suffix for x in __words(string_or_list)]

def __words(string_or_list):
    if type(string_or_list) == "list":
        return string_or_list
    return string_or_list.split()

# Handle manipulation functions.
# A handle passed to a PCM consists of:
#   product attributes dict ("cfg")
#   inherited modules dict (maps module name to PCM)
#   default value list (initially empty, modified by inheriting)
def __h_new():
    """Constructs a handle which is passed to PCM."""
    return (dict(), dict(), list())

def __h_inherited_modules(handle):
    """Returns PCM's inherited modules dict."""
    return handle[1]

def __h_cfg(handle):
    """Returns PCM's product configuration attributes dict.

    This function is also exported as rblf.cfg, and every PCM
    calls it at the beginning.
    """
    return handle[0]

def _setdefault(handle, attr):
    """If attribute has not been set, assigns default value to it.

    This function is exported as rblf.setdefault().
    Only list attributes are initialized this way. The default
    value is kept in the PCM's handle. Calling inherit() updates it.
    """
    cfg = handle[0]
    if cfg.get(attr) == None:
        cfg[attr] = list(handle[2])
    return cfg[attr]

def _inherit(handle, pcm_name, pcm):
    """Records inheritance.

    This function is exported as rblf.inherit, PCM calls it when
    a module is inherited.
    """
    cfg, inherited, default_lv = handle
    inherited[pcm_name] = pcm
    default_lv.append(_indirect(pcm_name))

    # Add inherited module reference to all configuration values
    for attr, val in cfg.items():
        if type(val) == "list":
            val.append(_indirect(pcm_name))

def _copy_if_exists(path_pair):
    """If from file exists, returns [from:to] pair."""
    value = path_pair.split(":", 2)

    # Check that l[0] exists
    return [":".join(value)] if rblf_file_exists(value[0]) else []

def _enforce_product_packages_exist(pkg_string_or_list):
    """Makes including non-existent modules in PRODUCT_PACKAGES an error."""

    #TODO(asmundak)
    pass

def _file_wildcard_exists(file_pattern):
    """Return True if there are files matching given bash pattern."""
    return len(rblf_wildcard(file_pattern)) > 0

def _find_and_copy(pattern, from_dir, to_dir):
    """Return a copy list for the files matching the pattern."""
    return ["%s/%s:%s/%s" % (from_dir, f, to_dir, f) for f in rblf_wildcard(pattern, from_dir)]

def _filter_out(pattern, text):
    """Return all the words from `text' that do not match any word in `pattern'.

    Args:
        pattern: string or list of words. '%' stands for wildcard (in regex terms, '.*')
        text: string or list of words
    Return:
        list of words
    """
    rex = __mk2regex(__words(pattern))
    res = []
    for w in __words(text):
        if not _regex_match(rex, w):
            res.append(w)
    return res

def _filter(pattern, text):
    """Return all the words in `text` that match `pattern`.

    Args:
        pattern: strings of words or a list. A word can contain '%',
         which stands for any sequence of characters.
        text: string or list of words.
    """
    rex = __mk2regex(__words(pattern))
    res = []
    for w in __words(text):
        if _regex_match(rex, w):
            res.append(w)
    return res

def __mk2regex(words):
    """Returns regular expression equivalent to Make pattern."""

    # TODO(asmundak): this will mishandle '\%'
    return "^(" + "|".join([w.replace("%", ".*", 1) for w in words]) + ")"

def _regex_match(regex, w):
    return rblf_regex(regex, w)

def _require_artifacts_in_path(paths, allowed_paths):
    """TODO."""
    pass

def _require_artifacts_in_path_relaxed(paths, allowed_paths):
    """TODO."""
    pass

def _expand_wildcard(pattern):
    """Expands shell wildcard pattern."""
    return rblf_wildcard(pattern)

def _mkerror(file, message = ""):
    """Prints error and stops."""
    fail("%s: %s. Stop" % (file, message))

def _mkwarning(file, message = ""):
    """Prints warning."""
    print("%s: warning: %s" % (file, message))

def _mkinfo(file, message = ""):
    """Prints info."""
    print(message)

def __get_options():
    """Returns struct containing runtime global settings."""
    settings = dict(
        format = "pretty",
        print_globals = False,
        rearrange = "",
        trace_modules = False,
        trace_variables = [],
    )
    for x in getattr(rblf_cli, "RBC_OUT", "").split(","):
        if x == "sort" or x == "unique":
            if settings["rearrange"]:
                fail("RBC_OUT: either sort or unique is allowed (and sort implies unique)")
            settings["rearrange"] = x
        elif x == "pretty" or x == "make":
            settings["format"] = x
        elif x == "global":
            settings["print_globals"] = True
        elif x != "":
            fail("RBC_OUT: got %s, should be one of: [pretty|make] [sort|unique]" % x)
    for x in getattr(rblf_cli, "RBC_DEBUG", "").split(","):
        if x == "!trace":
            settings["trace_modules"] = True
        elif x != "":
            settings["trace_variables"].append(x)
    return struct(**settings)

# Settings used during debugging.
_options = __get_options()
rblf = struct(
    addprefix = _addprefix,
    addsuffix = _addsuffix,
    copy_if_exists = _copy_if_exists,
    cfg = __h_cfg,
    enforce_product_packages_exist = _enforce_product_packages_exist,
    expand_wildcard = _expand_wildcard,
    file_exists = rblf_file_exists,
    file_wildcard_exists = _file_wildcard_exists,
    filter = _filter,
    filter_out = _filter_out,
    find_and_copy = _find_and_copy,
    global_init = _global_init,
    inherit = _inherit,
    indirect = _indirect,
    mkinfo = _mkinfo,
    mkerror = _mkerror,
    mkwarning = _mkwarning,
    printvars = _printvars,
    product_configuration = _product_configuration,
    require_artifacts_in_path = _require_artifacts_in_path,
    require_artifacts_in_path_relaxed = _require_artifacts_in_path_relaxed,
    setdefault = _setdefault,
    shell = rblf_shell,
    warning = _mkwarning,
)
