# 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,
)
