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

"""Skylib module containing file path manipulation functions.

NOTE: The functions in this module currently only support paths with Unix-style
path separators (forward slash, "/"); they do not handle Windows-style paths
with backslash separators or drive letters.
"""

def _basename(p):
    """Returns the basename (i.e., the file portion) of a path.

    Note that if `p` ends with a slash, this function returns an empty string.
    This matches the behavior of Python's `os.path.basename`, but differs from
    the Unix `basename` command (which would return the path segment preceding
    the final slash).

    Args:
      p: The path whose basename should be returned.

    Returns:
      The basename of the path, which includes the extension.
    """
    return p.rpartition("/")[-1]

def _dirname(p):
    """Returns the dirname of a path.

    The dirname is the portion of `p` up to but not including the file portion
    (i.e., the basename). Any slashes immediately preceding the basename are not
    included, unless omitting them would make the dirname empty.

    Args:
      p: The path whose dirname should be returned.

    Returns:
      The dirname of the path.
    """
    prefix, sep, _ = p.rpartition("/")
    if not prefix:
        return sep
    else:
        # If there are multiple consecutive slashes, strip them all out as Python's
        # os.path.dirname does.
        return prefix.rstrip("/")

def _is_absolute(path):
    """Returns `True` if `path` is an absolute path.

    Args:
      path: A path (which is a string).

    Returns:
      `True` if `path` is an absolute path.
    """
    return path.startswith("/") or (len(path) > 2 and path[1] == ":")

def _join(path, *others):
    """Joins one or more path components intelligently.

    This function mimics the behavior of Python's `os.path.join` function on POSIX
    platform. It returns the concatenation of `path` and any members of `others`,
    inserting directory separators before each component except the first. The
    separator is not inserted if the path up until that point is either empty or
    already ends in a separator.

    If any component is an absolute path, all previous components are discarded.

    Args:
      path: A path segment.
      *others: Additional path segments.

    Returns:
      A string containing the joined paths.
    """
    result = path

    for p in others:
        if _is_absolute(p):
            result = p
        elif not result or result.endswith("/"):
            result += p
        else:
            result += "/" + p

    return result

def _normalize(path):
    """Normalizes a path, eliminating double slashes and other redundant segments.

    This function mimics the behavior of Python's `os.path.normpath` function on
    POSIX platforms; specifically:

    - If the entire path is empty, "." is returned.
    - All "." segments are removed, unless the path consists solely of a single
      "." segment.
    - Trailing slashes are removed, unless the path consists solely of slashes.
    - ".." segments are removed as long as there are corresponding segments
      earlier in the path to remove; otherwise, they are retained as leading ".."
      segments.
    - Single and double leading slashes are preserved, but three or more leading
      slashes are collapsed into a single leading slash.
    - Multiple adjacent internal slashes are collapsed into a single slash.

    Args:
      path: A path.

    Returns:
      The normalized path.
    """
    if not path:
        return "."

    if path.startswith("//") and not path.startswith("///"):
        initial_slashes = 2
    elif path.startswith("/"):
        initial_slashes = 1
    else:
        initial_slashes = 0
    is_relative = (initial_slashes == 0)

    components = path.split("/")
    new_components = []

    for component in components:
        if component in ("", "."):
            continue
        if component == "..":
            if new_components and new_components[-1] != "..":
                # Only pop the last segment if it isn't another "..".
                new_components.pop()
            elif is_relative:
                # Preserve leading ".." segments for relative paths.
                new_components.append(component)
        else:
            new_components.append(component)

    path = "/".join(new_components)
    if not is_relative:
        path = ("/" * initial_slashes) + path

    return path or "."

def _relativize(path, start):
    """Returns the portion of `path` that is relative to `start`.

    Because we do not have access to the underlying file system, this
    implementation differs slightly from Python's `os.path.relpath` in that it
    will fail if `path` is not beneath `start` (rather than use parent segments to
    walk up to the common file system root).

    Relativizing paths that start with parent directory references only works if
    the path both start with the same initial parent references.

    Args:
      path: The path to relativize.
      start: The ancestor path against which to relativize.

    Returns:
      The portion of `path` that is relative to `start`.
    """
    segments = _normalize(path).split("/")
    start_segments = _normalize(start).split("/")
    if start_segments == ["."]:
        start_segments = []
    start_length = len(start_segments)

    if (path.startswith("/") != start.startswith("/") or
        len(segments) < start_length):
        fail("Path '%s' is not beneath '%s'" % (path, start))

    for ancestor_segment, segment in zip(start_segments, segments):
        if ancestor_segment != segment:
            fail("Path '%s' is not beneath '%s'" % (path, start))

    length = len(segments) - start_length
    result_segments = segments[-length:]
    return "/".join(result_segments)

def _replace_extension(p, new_extension):
    """Replaces the extension of the file at the end of a path.

    If the path has no extension, the new extension is added to it.

    Args:
      p: The path whose extension should be replaced.
      new_extension: The new extension for the file. The new extension should
          begin with a dot if you want the new filename to have one.

    Returns:
      The path with the extension replaced (or added, if it did not have one).
    """
    return _split_extension(p)[0] + new_extension

def _split_extension(p):
    """Splits the path `p` into a tuple containing the root and extension.

    Leading periods on the basename are ignored, so
    `path.split_extension(".bashrc")` returns `(".bashrc", "")`.

    Args:
      p: The path whose root and extension should be split.

    Returns:
      A tuple `(root, ext)` such that the root is the path without the file
      extension, and `ext` is the file extension (which, if non-empty, contains
      the leading dot). The returned tuple always satisfies the relationship
      `root + ext == p`.
    """
    b = _basename(p)
    last_dot_in_basename = b.rfind(".")

    # If there is no dot or the only dot in the basename is at the front, then
    # there is no extension.
    if last_dot_in_basename <= 0:
        return (p, "")

    dot_distance_from_end = len(b) - last_dot_in_basename
    return (p[:-dot_distance_from_end], p[-dot_distance_from_end:])

paths = struct(
    basename = _basename,
    dirname = _dirname,
    is_absolute = _is_absolute,
    join = _join,
    normalize = _normalize,
    relativize = _relativize,
    replace_extension = _replace_extension,
    split_extension = _split_extension,
)
