# Copyright 2015 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.

"""Utility functions not specific to the rust toolchain."""

load("@bazel_tools//tools/cpp:toolchain_utils.bzl", find_rules_cc_toolchain = "find_cpp_toolchain")
load(":providers.bzl", "BuildInfo", "CrateInfo", "DepInfo", "DepVariantInfo")

UNSUPPORTED_FEATURES = [
    "thin_lto",
    "module_maps",
    "use_header_modules",
    "fdo_instrument",
    "fdo_optimize",
]

def find_toolchain(ctx):
    """Finds the first rust toolchain that is configured.

    Args:
        ctx (ctx): The ctx object for the current target.

    Returns:
        rust_toolchain: A Rust toolchain context.
    """
    return ctx.toolchains[Label("//rust:toolchain")]

def find_cc_toolchain(ctx):
    """Extracts a CcToolchain from the current target's context

    Args:
        ctx (ctx): The current target's rule context object

    Returns:
        tuple: A tuple of (CcToolchain, FeatureConfiguration)
    """
    cc_toolchain = find_rules_cc_toolchain(ctx)

    feature_configuration = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        requested_features = ctx.features,
        unsupported_features = UNSUPPORTED_FEATURES + ctx.disabled_features,
    )
    return cc_toolchain, feature_configuration

# TODO: Replace with bazel-skylib's `path.dirname`. This requires addressing some
# dependency issues or generating docs will break.
def relativize(path, start):
    """Returns the relative path from start to path.

    Args:
        path (str): The path to relativize.
        start (str): The ancestor path against which to relativize.

    Returns:
        str: The portion of `path` that is relative to `start`.
    """
    src_parts = _path_parts(start)
    dest_parts = _path_parts(path)
    n = 0
    for src_part, dest_part in zip(src_parts, dest_parts):
        if src_part != dest_part:
            break
        n += 1

    relative_path = ""
    for _ in range(n, len(src_parts)):
        relative_path += "../"
    relative_path += "/".join(dest_parts[n:])

    return relative_path

def _path_parts(path):
    """Takes a path and returns a list of its parts with all "." elements removed.

    The main use case of this function is if one of the inputs to relativize()
    is a relative path, such as "./foo".

    Args:
      path (str): A string representing a unix path

    Returns:
      list: A list containing the path parts with all "." elements removed.
    """
    path_parts = path.split("/")
    return [part for part in path_parts if part != "."]

def get_lib_name(lib):
    """Returns the name of a library artifact, eg. libabc.a -> abc

    Args:
        lib (File): A library file

    Returns:
        str: The name of the library
    """
    # On macos and windows, dynamic/static libraries always end with the
    # extension and potential versions will be before the extension, and should
    # be part of the library name.
    # On linux, the version usually comes after the extension.
    # So regardless of the platform we want to find the extension and make
    # everything left to it the library name.

    # Search for the extension - starting from the right - by removing any
    # trailing digit.
    comps = lib.basename.split(".")
    for comp in reversed(comps):
        if comp.isdigit():
            comps.pop()
        else:
            break

    # The library name is now everything minus the extension.
    libname = ".".join(comps[:-1])

    if libname.startswith("lib"):
        return libname[3:]
    else:
        return libname

def abs(value):
    """Returns the absolute value of a number.

    Args:
      value (int): A number.

    Returns:
      int: The absolute value of the number.
    """
    if value < 0:
        return -value
    return value

def determine_output_hash(crate_root, label):
    """Generates a hash of the crate root file's path.

    Args:
        crate_root (File): The crate's root file (typically `lib.rs`).
        label (Label): The label of the target.

    Returns:
        str: A string representation of the hash.
    """

    # Take the absolute value of hash() since it could be negative.
    h = abs(hash(crate_root.path) + hash(repr(label)))
    return repr(h)

def get_preferred_artifact(library_to_link, use_pic):
    """Get the first available library to link from a LibraryToLink object.

    Args:
        library_to_link (LibraryToLink): See the followg links for additional details:
            https://docs.bazel.build/versions/master/skylark/lib/LibraryToLink.html
        use_pic: If set, prefers pic_static_library over static_library.

    Returns:
        File: Returns the first valid library type (only one is expected)
    """
    if use_pic:
        # Order consistent with https://github.com/bazelbuild/bazel/blob/815dfdabb7df31d4e99b6fc7616ff8e2f9385d98/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingContext.java#L437.
        return (
            library_to_link.pic_static_library or
            library_to_link.static_library or
            library_to_link.interface_library or
            library_to_link.dynamic_library
        )
    else:
        return (
            library_to_link.static_library or
            library_to_link.pic_static_library or
            library_to_link.interface_library or
            library_to_link.dynamic_library
        )

def _expand_location(ctx, env, data):
    """A trivial helper for `_expand_locations`

    Args:
        ctx (ctx): The rule's context object
        env (str): The value possibly containing location macros to expand.
        data (sequence of Targets): see `_expand_locations`

    Returns:
        string: The location-macro expanded version of the string.
    """
    for directive in ("$(execpath ", "$(location "):
        if directive in env:
            # build script runner will expand pwd to execroot for us
            env = env.replace(directive, "${pwd}/" + directive)
    return ctx.expand_location(env, data)

def expand_dict_value_locations(ctx, env, data):
    """Performs location-macro expansion on string values.

    $(execroot ...) and $(location ...) are prefixed with ${pwd},
    which process_wrapper and build_script_runner will expand at run time
    to the absolute path. This is necessary because include_str!() is relative
    to the currently compiled file, and build scripts run relative to the
    manifest dir, so we can not use execroot-relative paths.

    $(rootpath ...) is unmodified, and is useful for passing in paths via
    rustc_env that are encoded in the binary with env!(), but utilized at
    runtime, such as in tests. The absolute paths are not usable in this case,
    as compilation happens in a separate sandbox folder, so when it comes time
    to read the file at runtime, the path is no longer valid.

    See [`expand_location`](https://docs.bazel.build/versions/main/skylark/lib/ctx.html#expand_location) for detailed documentation.

    Args:
        ctx (ctx): The rule's context object
        env (dict): A dict whose values we iterate over
        data (sequence of Targets): The targets which may be referenced by
            location macros. This is expected to be the `data` attribute of
            the target, though may have other targets or attributes mixed in.

    Returns:
        dict: A dict of environment variables with expanded location macros
    """
    return dict([(k, _expand_location(ctx, v, data)) for (k, v) in env.items()])

def expand_list_element_locations(ctx, args, data):
    """Performs location-macro expansion on a list of string values.

    $(execroot ...) and $(location ...) are prefixed with ${pwd},
    which process_wrapper and build_script_runner will expand at run time
    to the absolute path.

    See [`expand_location`](https://docs.bazel.build/versions/main/skylark/lib/ctx.html#expand_location) for detailed documentation.

    Args:
        ctx (ctx): The rule's context object
        args (list): A list we iterate over
        data (sequence of Targets): The targets which may be referenced by
            location macros. This is expected to be the `data` attribute of
            the target, though may have other targets or attributes mixed in.

    Returns:
        list: A list of arguments with expanded location macros
    """
    return [_expand_location(ctx, arg, data) for arg in args]

def name_to_crate_name(name):
    """Converts a build target's name into the name of its associated crate.

    Crate names cannot contain certain characters, such as -, which are allowed
    in build target names. All illegal characters will be converted to
    underscores.

    This is a similar conversion as that which cargo does, taking a
    `Cargo.toml`'s `package.name` and canonicalizing it

    Note that targets can specify the `crate_name` attribute to customize their
    crate name; in situations where this is important, use the
    compute_crate_name() function instead.

    Args:
        name (str): The name of the target.

    Returns:
        str: The name of the crate for this target.
    """
    for illegal in ("-", "/"):
        name = name.replace(illegal, "_")
    return name

def _invalid_chars_in_crate_name(name):
    """Returns any invalid chars in the given crate name.

    Args:
        name (str): Name to test.

    Returns:
        list: List of invalid characters in the crate name.
    """

    return dict([(c, ()) for c in name.elems() if not (c.isalnum() or c == "_")]).keys()

def compute_crate_name(workspace_name, label, toolchain, name_override = None):
    """Returns the crate name to use for the current target.

    Args:
        workspace_name (string): The current workspace name.
        label (struct): The label of the current target.
        toolchain (struct): The toolchain in use for the target.
        name_override (String): An optional name to use (as an override of label.name).

    Returns:
        str: The crate name to use for this target.
    """
    if name_override:
        invalid_chars = _invalid_chars_in_crate_name(name_override)
        if invalid_chars:
            fail("Crate name '{}' contains invalid character(s): {}".format(
                name_override,
                " ".join(invalid_chars),
            ))
        return name_override

    if (toolchain and label and toolchain._rename_first_party_crates and
        should_encode_label_in_crate_name(workspace_name, label, toolchain._third_party_dir)):
        crate_name = encode_label_as_crate_name(label.package, label.name)
    else:
        crate_name = name_to_crate_name(label.name)

    invalid_chars = _invalid_chars_in_crate_name(crate_name)
    if invalid_chars:
        fail(
            "Crate name '{}' ".format(crate_name) +
            "derived from Bazel target name '{}' ".format(label.name) +
            "contains invalid character(s): {}\n".format(" ".join(invalid_chars)) +
            "Consider adding a crate_name attribute to set a valid crate name",
        )
    return crate_name

def dedent(doc_string):
    """Remove any common leading whitespace from every line in text.

    This functionality is similar to python's `textwrap.dedent` functionality
    https://docs.python.org/3/library/textwrap.html#textwrap.dedent

    Args:
        doc_string (str): A docstring style string

    Returns:
        str: A string optimized for stardoc rendering
    """
    lines = doc_string.splitlines()
    if not lines:
        return doc_string

    # If the first line is empty, use the second line
    first_line = lines[0]
    if not first_line:
        first_line = lines[1]

    # Detect how much space prepends the first line and subtract that from all lines
    space_count = len(first_line) - len(first_line.lstrip())

    # If there are no leading spaces, do not alter the docstring
    if space_count == 0:
        return doc_string
    else:
        # Remove the leading block of spaces from the current line
        block = " " * space_count
        return "\n".join([line.replace(block, "", 1).rstrip() for line in lines])

def make_static_lib_symlink(actions, rlib_file):
    """Add a .a symlink to an .rlib file.

    The name of the symlink is derived from the <name> of the <name>.rlib file as follows:
    * `<name>.a`, if <name> starts with `lib`
    * `lib<name>.a`, otherwise.

    For example, the name of the symlink for
    * `libcratea.rlib` is `libcratea.a`
    * `crateb.rlib` is `libcrateb.a`.

    Args:
        actions (actions): The rule's context actions object.
        rlib_file (File): The file to symlink, which must end in .rlib.

    Returns:
        The symlink's File.
    """
    if not rlib_file.basename.endswith(".rlib"):
        fail("file is not an .rlib: ", rlib_file.basename)
    basename = rlib_file.basename[:-5]
    if not basename.startswith("lib"):
        basename = "lib" + basename
    dot_a = actions.declare_file(basename + ".a", sibling = rlib_file)
    actions.symlink(output = dot_a, target_file = rlib_file)
    return dot_a

def is_exec_configuration(ctx):
    """Determine if a context is building for the exec configuration.

    This is helpful when processing command line flags that should apply
    to the target configuration but not the exec configuration.

    Args:
        ctx (ctx): The ctx object for the current target.

    Returns:
        True if the exec configuration is detected, False otherwise.
    """

    # TODO(djmarcin): Is there any better way to determine cfg=exec?
    return ctx.genfiles_dir.path.find("-exec-") != -1

def transform_deps(deps):
    """Transforms a [Target] into [DepVariantInfo].

    This helper function is used to transform ctx.attr.deps and ctx.attr.proc_macro_deps into
    [DepVariantInfo].

    Args:
        deps (list of Targets): Dependencies coming from ctx.attr.deps or ctx.attr.proc_macro_deps

    Returns:
        list of DepVariantInfos.
    """
    return [DepVariantInfo(
        crate_info = dep[CrateInfo] if CrateInfo in dep else None,
        dep_info = dep[DepInfo] if DepInfo in dep else None,
        build_info = dep[BuildInfo] if BuildInfo in dep else None,
        cc_info = dep[CcInfo] if CcInfo in dep else None,
    ) for dep in deps]

def get_import_macro_deps(ctx):
    """Returns a list of targets to be added to proc_macro_deps.

    Args:
        ctx (struct): the ctx of the current target.

    Returns:
        list of Targets. Either empty (if the fake import macro implementation
        is being used), or a singleton list with the real implementation.
    """
    if ctx.attr._import_macro_dep.label.name == "fake_import_macro_impl":
        return []

    return [ctx.attr._import_macro_dep]

def should_encode_label_in_crate_name(workspace_name, label, third_party_dir):
    """Determines if the crate's name should include the Bazel label, encoded.

    Crate names may only encode the label if the target is in the current repo,
    the target is not in the third_party_dir, and the current repo is not
    rules_rust.

    Args:
        workspace_name (string): The name of the current workspace.
        label (Label): The package in question.
        third_party_dir (string): The directory in which third-party packages are kept.

    Returns:
        True if the crate name should encode the label, False otherwise.
    """

    # TODO(hlopko): This code assumes a monorepo; make it work with external
    # repositories as well.
    return (
        workspace_name != "rules_rust" and
        not label.workspace_root and
        not ("//" + label.package + "/").startswith(third_party_dir + "/")
    )

# This is a list of pairs, where the first element of the pair is a character
# that is allowed in Bazel package or target names but not in crate names; and
# the second element is an encoding of that char suitable for use in a crate
# name.
_encodings = (
    (":", "c"),
    ("!", "bang"),
    ("%", "perc"),
    ("@", "at"),
    ("^", "caret"),
    ("`", "bt"),
    (" ", "sp"),
    ("\"", "dq"),
    ("#", "hash"),
    ("$", "dollar"),
    ("&", "amp"),
    ("'", "sq"),
    ("(", "lp"),
    (")", "rp"),
    ("*", "star"),
    ("-", "d"),
    ("+", "plus"),
    (",", "comma"),
    (";", "semi"),
    ("<", "langle"),
    ("=", "eq"),
    (">", "rangle"),
    ("?", "qm"),
    ("[", "lbrack"),
    ("]", "rbrack"),
    ("{", "lbrace"),
    ("|", "pipe"),
    ("}", "rbrace"),
    ("~", "tilde"),
    ("/", "s"),
    (".", "dot"),
)

# For each of the above encodings, we generate two substitution rules: one that
# ensures any occurrences of the encodings themselves in the package/target
# aren't clobbered by this translation, and one that does the encoding itself.
# We also include a rule that protects the clobbering-protection rules from
# getting clobbered.
_substitutions = [("_z", "_zz_")] + [
    subst
    for (pattern, replacement) in _encodings
    for subst in (
        ("_{}_".format(replacement), "_z{}_".format(replacement)),
        (pattern, "_{}_".format(replacement)),
    )
]

# Expose the substitutions for testing only.
substitutions_for_testing = _substitutions

def encode_label_as_crate_name(package, name):
    """Encodes the package and target names in a format suitable for a crate name.

    Args:
        package (string): The package of the target in question.
        name (string): The name of the target in question.

    Returns:
        A string that encodes the package and target name, to be used as the crate's name.
    """
    return _encode_raw_string(package + ":" + name)

def _encode_raw_string(str):
    """Encodes a string using the above encoding format.

    Args:
        str (string): The string to be encoded.

    Returns:
        An encoded version of the input string.
    """
    return _replace_all(str, _substitutions)

# Expose the underlying encoding function for testing only.
encode_raw_string_for_testing = _encode_raw_string

def decode_crate_name_as_label_for_testing(crate_name):
    """Decodes a crate_name that was encoded by encode_label_as_crate_name.

    This is used to check that the encoding is bijective; it is expected to only
    be used in tests.

    Args:
        crate_name (string): The name of the crate.

    Returns:
        A string representing the Bazel label (package and target).
    """
    return _replace_all(crate_name, [(t[1], t[0]) for t in _substitutions])

def _replace_all(string, substitutions):
    """Replaces occurrences of the given patterns in `string`.

    There are a few reasons this looks complicated:
    * The substitutions are performed with some priority, i.e. patterns that are
      listed first in `substitutions` are higher priority than patterns that are
      listed later.
    * We also take pains to avoid doing replacements that overlap with each
      other, since overlaps invalidate pattern matches.
    * To avoid hairy offset invalidation, we apply the substitutions
      right-to-left.
    * To avoid the "_quote" -> "_quotequote_" rule introducing new pattern
      matches later in the string during decoding, we take the leftmost
      replacement, in cases of overlap.  (Note that no rule can induce new
      pattern matches *earlier* in the string.) (E.g. "_quotedot_" encodes to
      "_quotequote_dot_". Note that "_quotequote_" and "_dot_" both occur in
      this string, and overlap.).

    Args:
        string (string): the string in which the replacements should be performed.
        substitutions: the list of patterns and replacements to apply.

    Returns:
        A string with the appropriate substitutions performed.
    """

    # Find the highest-priority pattern matches for each string index, going
    # left-to-right and skipping indices that are already involved in a
    # pattern match.
    plan = {}
    matched_indices_set = {}
    for pattern_start in range(len(string)):
        if pattern_start in matched_indices_set:
            continue
        for (pattern, replacement) in substitutions:
            if not string.startswith(pattern, pattern_start):
                continue
            length = len(pattern)
            plan[pattern_start] = (length, replacement)
            matched_indices_set.update([(pattern_start + i, True) for i in range(length)])
            break

    # Execute the replacement plan, working from right to left.
    for pattern_start in sorted(plan.keys(), reverse = True):
        length, replacement = plan[pattern_start]
        after_pattern = pattern_start + length
        string = string[:pattern_start] + replacement + string[after_pattern:]

    return string
