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

###############################################################################
# Vendored in from bazelbuild/bazel (tools/python/runfiles/runfiles.py) at    #
# commit 6c60a8ec049b6b8540c473969dd7bd1dad46acb9 (2019-07-19). See           #
# //python/runfiles:BUILD for details.                                        #
###############################################################################

"""Runfiles lookup library for Bazel-built Python binaries and tests.

USAGE:

1.  Depend on this runfiles library from your build rule:

      py_binary(
          name = "my_binary",
          ...
          deps = ["@bazel_tools//tools/python/runfiles"],
      )

2.  Import the runfiles library.

      from bazel_tools.tools.python.runfiles import runfiles

3.  Create a Runfiles object and use rlocation to look up runfile paths:

      r = runfiles.Create()
      ...
      with open(r.Rlocation("my_workspace/path/to/my/data.txt"), "r") as f:
        contents = f.readlines()
        ...

    The code above creates a manifest- or directory-based implementations based
    on the environment variables in os.environ. See `Create()` for more info.

    If you want to explicitly create a manifest- or directory-based
    implementations, you can do so as follows:

      r1 = runfiles.CreateManifestBased("path/to/foo.runfiles_manifest")

      r2 = runfiles.CreateDirectoryBased("path/to/foo.runfiles/")

    If you want to start subprocesses that also need runfiles, you need to set
    the right environment variables for them:

      import subprocess
      from bazel_tools.tools.python.runfiles import runfiles

      r = runfiles.Create()
      env = {}
      ...
      env.update(r.EnvVars())
      p = subprocess.Popen([r.Rlocation("path/to/binary")], env, ...)
"""

import os
import posixpath

if False:
    # Mypy needs these symbols imported, but since they only exist in python 3.5+,
    # this import may fail at runtime. Luckily mypy can follow this conditional import.
    from typing import Callable, Dict, Optional, Tuple, Union

def CreateManifestBased(manifest_path):
    # type: (str) -> _Runfiles
    return _Runfiles(_ManifestBased(manifest_path))


def CreateDirectoryBased(runfiles_dir_path):
    # type: (str) -> _Runfiles
    return _Runfiles(_DirectoryBased(runfiles_dir_path))


def Create(env=None):
    # type: (Optional[Dict[str, str]]) -> Optional[_Runfiles]
    """Returns a new `Runfiles` instance.

    The returned object is either:
    - manifest-based, meaning it looks up runfile paths from a manifest file, or
    - directory-based, meaning it looks up runfile paths under a given directory
      path

    If `env` contains "RUNFILES_MANIFEST_FILE" with non-empty value, this method
    returns a manifest-based implementation. The object eagerly reads and caches
    the whole manifest file upon instantiation; this may be relevant for
    performance consideration.

    Otherwise, if `env` contains "RUNFILES_DIR" with non-empty value (checked in
    this priority order), this method returns a directory-based implementation.

    If neither cases apply, this method returns null.

    Args:
      env: {string: string}; optional; the map of environment variables. If None,
          this function uses the environment variable map of this process.
    Raises:
      IOError: if some IO error occurs.
    """
    env_map = os.environ if env is None else env
    manifest = env_map.get("RUNFILES_MANIFEST_FILE")
    if manifest:
        return CreateManifestBased(manifest)

    directory = env_map.get("RUNFILES_DIR")
    if directory:
        return CreateDirectoryBased(directory)

    return None


class _Runfiles(object):
    """Returns the runtime location of runfiles.

    Runfiles are data-dependencies of Bazel-built binaries and tests.
    """

    def __init__(self, strategy):
        # type: (Union[_ManifestBased, _DirectoryBased]) -> None
        self._strategy = strategy

    def Rlocation(self, path):
        # type: (str) -> Optional[str]
        """Returns the runtime path of a runfile.

        Runfiles are data-dependencies of Bazel-built binaries and tests.

        The returned path may not be valid. The caller should check the path's
        validity and that the path exists.

        The function may return None. In that case the caller can be sure that the
        rule does not know about this data-dependency.

        Args:
          path: string; runfiles-root-relative path of the runfile
        Returns:
          the path to the runfile, which the caller should check for existence, or
          None if the method doesn't know about this runfile
        Raises:
          TypeError: if `path` is not a string
          ValueError: if `path` is None or empty, or it's absolute or not normalized
        """
        if not path:
            raise ValueError()
        if not isinstance(path, str):
            raise TypeError()
        if (
            path.startswith("../")
            or "/.." in path
            or path.startswith("./")
            or "/./" in path
            or path.endswith("/.")
            or "//" in path
        ):
            raise ValueError('path is not normalized: "%s"' % path)
        if path[0] == "\\":
            raise ValueError('path is absolute without a drive letter: "%s"' % path)
        if os.path.isabs(path):
            return path
        return self._strategy.RlocationChecked(path)

    def EnvVars(self):
        # type: () -> Dict[str, str]
        """Returns environment variables for subprocesses.

        The caller should set the returned key-value pairs in the environment of
        subprocesses in case those subprocesses are also Bazel-built binaries that
        need to use runfiles.

        Returns:
          {string: string}; a dict; keys are environment variable names, values are
          the values for these environment variables
        """
        return self._strategy.EnvVars()


class _ManifestBased(object):
    """`Runfiles` strategy that parses a runfiles-manifest to look up runfiles."""

    def __init__(self, path):
        # type: (str) -> None
        if not path:
            raise ValueError()
        if not isinstance(path, str):
            raise TypeError()
        self._path = path
        self._runfiles = _ManifestBased._LoadRunfiles(path)

    def RlocationChecked(self, path):
        # type: (str) -> Optional[str]
        return self._runfiles.get(path)

    @staticmethod
    def _LoadRunfiles(path):
        # type: (str) -> Dict[str, str]
        """Loads the runfiles manifest."""
        result = {}
        with open(path, "r") as f:
            for line in f:
                line = line.strip()
                if line:
                    tokens = line.split(" ", 1)
                    if len(tokens) == 1:
                        result[line] = line
                    else:
                        result[tokens[0]] = tokens[1]
        return result

    def _GetRunfilesDir(self):
        # type: () -> str
        if self._path.endswith("/MANIFEST") or self._path.endswith("\\MANIFEST"):
            return self._path[: -len("/MANIFEST")]
        elif self._path.endswith(".runfiles_manifest"):
            return self._path[: -len("_manifest")]
        else:
            return ""

    def EnvVars(self):
        # type: () -> Dict[str, str]
        directory = self._GetRunfilesDir()
        return {
            "RUNFILES_MANIFEST_FILE": self._path,
            "RUNFILES_DIR": directory,
            # TODO(laszlocsomor): remove JAVA_RUNFILES once the Java launcher can
            # pick up RUNFILES_DIR.
            "JAVA_RUNFILES": directory,
        }


class _DirectoryBased(object):
    """`Runfiles` strategy that appends runfiles paths to the runfiles root."""

    def __init__(self, path):
        # type: (str) -> None
        if not path:
            raise ValueError()
        if not isinstance(path, str):
            raise TypeError()
        self._runfiles_root = path

    def RlocationChecked(self, path):
        # type: (str) -> str

        # Use posixpath instead of os.path, because Bazel only creates a runfiles
        # tree on Unix platforms, so `Create()` will only create a directory-based
        # runfiles strategy on those platforms.
        return posixpath.join(self._runfiles_root, path)

    def EnvVars(self):
        # type: () -> Dict[str, str]
        return {
            "RUNFILES_DIR": self._runfiles_root,
            # TODO(laszlocsomor): remove JAVA_RUNFILES once the Java launcher can
            # pick up RUNFILES_DIR.
            "JAVA_RUNFILES": self._runfiles_root,
        }


def _PathsFrom(
    argv0, runfiles_mf, runfiles_dir, is_runfiles_manifest, is_runfiles_directory
):
    # type: (str, str, str, Callable[[str], bool], Callable[[str], bool]) -> Tuple[str, str]
    """Discover runfiles manifest and runfiles directory paths.

    Args:
      argv0: string; the value of sys.argv[0]
      runfiles_mf: string; the value of the RUNFILES_MANIFEST_FILE environment
        variable
      runfiles_dir: string; the value of the RUNFILES_DIR environment variable
      is_runfiles_manifest: lambda(string):bool; returns true if the argument is
        the path of a runfiles manifest file
      is_runfiles_directory: lambda(string):bool; returns true if the argument is
        the path of a runfiles directory

    Returns:
      (string, string) pair, first element is the path to the runfiles manifest,
      second element is the path to the runfiles directory. If the first element
      is non-empty, then is_runfiles_manifest returns true for it. Same goes for
      the second element and is_runfiles_directory respectively. If both elements
      are empty, then this function could not find a manifest or directory for
      which is_runfiles_manifest or is_runfiles_directory returns true.
    """
    mf_alid = is_runfiles_manifest(runfiles_mf)
    dir_valid = is_runfiles_directory(runfiles_dir)

    if not mf_alid and not dir_valid:
        runfiles_mf = argv0 + ".runfiles/MANIFEST"
        runfiles_dir = argv0 + ".runfiles"
        mf_alid = is_runfiles_manifest(runfiles_mf)
        dir_valid = is_runfiles_directory(runfiles_dir)
        if not mf_alid:
            runfiles_mf = argv0 + ".runfiles_manifest"
            mf_alid = is_runfiles_manifest(runfiles_mf)

    if not mf_alid and not dir_valid:
        return ("", "")

    if not mf_alid:
        runfiles_mf = runfiles_dir + "/MANIFEST"
        mf_alid = is_runfiles_manifest(runfiles_mf)
        if not mf_alid:
            runfiles_mf = runfiles_dir + "_manifest"
            mf_alid = is_runfiles_manifest(runfiles_mf)

    if not dir_valid:
        runfiles_dir = runfiles_mf[:-9]  # "_manifest" or "/MANIFEST"
        dir_valid = is_runfiles_directory(runfiles_dir)

    return (runfiles_mf if mf_alid else "", runfiles_dir if dir_valid else "")
