# 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.
"""Runfiles lookup library for Bazel-built Python binaries and tests.

Usage:

from bazel_tools.tools.runfiles import runfiles

r = runfiles.Create()
with open(r.Rlocation("io_bazel/foo/bar.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.runfiles import runfiles

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

import os
import posixpath


def CreateManifestBased(manifest_path):
  return _Runfiles(_ManifestBased(manifest_path))


def CreateDirectoryBased(runfiles_dir_path):
  return _Runfiles(_DirectoryBased(runfiles_dir_path))


def Create(env=None):
  """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):
    self._strategy = strategy

  def Rlocation(self, path):
    """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 contains
        uplevel references
    """
    if not path:
      raise ValueError()
    if not isinstance(path, str):
      raise TypeError()
    if ".." in path:
      raise ValueError("path contains uplevel references: \"%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):
    """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):
    if not path:
      raise ValueError()
    if not isinstance(path, str):
      raise TypeError()
    self._path = path
    self._runfiles = _ManifestBased._LoadRunfiles(path)

  def RlocationChecked(self, path):
    return self._runfiles.get(path)

  @staticmethod
  def _LoadRunfiles(path):
    """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):
    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):
    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):
    if not path:
      raise ValueError()
    if not isinstance(path, str):
      raise TypeError()
    self._runfiles_root = path

  def RlocationChecked(self, path):
    # 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):
    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,
    }
