# Copyright 2017 The Bazel Authors. All rights reserved.
#
# 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
#
#    http://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.

# Definitions for handling path re-mapping, to support short module names.
# See pathMapping doc: https://github.com/Microsoft/TypeScript/issues/5039
#
# This reads the module_root and module_name attributes from typescript rules in
# the transitive closure, rolling these up to provide a mapping to the
# TypeScript compiler and to editors.
#
"""Module mappings.
"""

def _get_deps(attrs, names):
    return [
        d
        for n in names
        if hasattr(attrs, n)
        for d in getattr(attrs, n)
    ]

# Traverse 'srcs' in addition so that we can go across a genrule
_MODULE_MAPPINGS_DEPS_NAMES = ["deps", "srcs", "_helpers"]

_DEBUG = False

def debug(msg, values = ()):
    if _DEBUG:
        print(msg % values)

def get_module_mappings(label, attrs, srcs = [], workspace_name = None, mappings_attr = "es6_module_mappings"):
    """Returns the module_mappings from the given attrs.

    Collects a {module_name - module_root} hash from all transitive dependencies,
    checking for collisions. If a module has a non-empty `module_root` attribute,
    all sources underneath it are treated as if they were rooted at a folder
    `module_name`.

    Args:
      label: The label declaring a module mapping
      attrs: Attributes on that label
      srcs: The srcs attribute, used to validate that these are under the root
      workspace_name: name of the workspace where the user is building
      mappings_attr: name of the attribute we use to hand down transitive data

    Returns:
      the module_mappings from the given attrs.
    """
    mappings = dict()
    all_deps = _get_deps(attrs, names = _MODULE_MAPPINGS_DEPS_NAMES)
    for dep in all_deps:
        if not hasattr(dep, mappings_attr):
            continue
        for k, v in getattr(dep, mappings_attr).items():
            if k in mappings and mappings[k] != v:
                fail(("duplicate module mapping at %s: %s maps to both %s and %s" %
                      (label, k, mappings[k], v)), "deps")
            mappings[k] = v
    if ((hasattr(attrs, "module_name") and attrs.module_name) or
        (hasattr(attrs, "module_root") and attrs.module_root)):
        mn = attrs.module_name
        if not mn:
            mn = label.name
        mr = "/".join([p for p in [
            workspace_name or label.workspace_root,
            label.package,
        ] if p])
        if attrs.module_root and attrs.module_root != ".":
            mr = "%s/%s" % (mr, attrs.module_root)
            if attrs.module_root.endswith(".ts"):
                if workspace_name:
                    mr = mr.replace(".d.ts", "")

                # Validate that sources are underneath the module root.
                # module_roots ending in .ts are a special case, they are used to
                # restrict what's exported from a build rule, e.g. only exports from a
                # specific index.d.ts file. For those, not every source must be under the
                # given module root.

            else:
                for s in srcs:
                    if not s.short_path.startswith(mr):
                        fail(("all sources must be under module root: %s, but found: %s" %
                              (mr, s.short_path)))
        if mn in mappings and mappings[mn] != mr:
            fail(("duplicate module mapping at %s: %s maps to both %s and %s" %
                  (label, mn, mappings[mn], mr)), "deps")
        mappings[mn] = mr

    debug("Mappings at %s: %s", (label, mappings))
    return mappings

def _module_mappings_aspect_impl(target, ctx):
    mappings = get_module_mappings(target.label, ctx.rule.attr)
    return struct(es6_module_mappings = mappings)

module_mappings_aspect = aspect(
    _module_mappings_aspect_impl,
    attr_aspects = _MODULE_MAPPINGS_DEPS_NAMES,
)

# When building a mapping for use at runtime, we need paths to be relative to
# the runfiles directory. This requires the workspace_name to be prefixed on
# each module root.
def _module_mappings_runtime_aspect_impl(target, ctx):
    if target.label.workspace_root:
        # We need the workspace_name for the target being visited.
        # Skylark doesn't have this - instead they have a workspace_root
        # which looks like "external/repo_name" - so grab the second path segment.
        # TODO(alexeagle): investigate a better way to get the workspace name
        workspace_name = target.label.workspace_root.split("/")[1]
    else:
        workspace_name = ctx.workspace_name
    mappings = get_module_mappings(
        target.label,
        ctx.rule.attr,
        workspace_name = workspace_name,
        mappings_attr = "runfiles_module_mappings",
    )
    return struct(runfiles_module_mappings = mappings)

module_mappings_runtime_aspect = aspect(
    _module_mappings_runtime_aspect_impl,
    attr_aspects = _MODULE_MAPPINGS_DEPS_NAMES,
)
