#!/usr/bin/env python

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import sys

# The Python interpreter unconditionally prepends the directory containing this
# script (following symlinks) to the import path. This is the cause of #9239,
# and is a special case of #7091. We therefore explicitly delete that entry.
# TODO(#7091): Remove this hack when no longer necessary.
del sys.path[0]

import os
import re
import shutil
import subprocess
import tempfile
import zipfile
import collections

# Return True if running on Windows
def IsWindows():
  return os.name == 'nt'

def GetWindowsPathWithUNCPrefix(path):
  """Adds UNC prefix after getting a normalized absolute Windows path.

  No-op for non-Windows platforms or if running under python2.
  """
  path = path.strip()

  # No need to add prefix for non-Windows platforms.
  # And \\?\ doesn't work in python 2
  if not IsWindows() or sys.version_info[0] < 3:
    return path

  # Lets start the unicode fun
  unicode_prefix = '\\\\?\\'
  if path.startswith(unicode_prefix):
    return path

  # os.path.abspath returns a normalized absolute path
  return unicode_prefix + os.path.abspath(path)

def HasWindowsExecutableExtension(path):
  return path.endswith('.exe') or path.endswith('.com') or path.endswith('.bat')

PYTHON_BINARY = '%python_binary%'
if IsWindows() and not HasWindowsExecutableExtension(PYTHON_BINARY):
  PYTHON_BINARY = PYTHON_BINARY + '.exe'

def SearchPath(name):
  """Finds a file in a given search path."""
  search_path = os.getenv('PATH', os.defpath).split(os.pathsep)
  for directory in search_path:
    if directory:
      path = os.path.join(directory, name)
      if os.path.isfile(path) and os.access(path, os.X_OK):
        return path
  return None

def IsRunningFromZip():
  return %is_zipfile%

def FindPythonBinary(module_space):
  """Finds the real Python binary if it's not a normal absolute path."""
  if PYTHON_BINARY.startswith('//'):
    # Case 1: Path is a label. Not supported yet.
    raise AssertionError(
      'Bazel does not support execution of Python interpreters via labels yet')
  elif os.path.isabs(PYTHON_BINARY):
    # Case 2: Absolute path.
    return PYTHON_BINARY
  # Use normpath() to convert slashes to os.sep on Windows.
  elif os.sep in os.path.normpath(PYTHON_BINARY):
    # Case 3: Path is relative to the repo root.
    return os.path.join(module_space, PYTHON_BINARY)
  else:
    # Case 4: Path has to be looked up in the search path.
    return SearchPath(PYTHON_BINARY)

def CreatePythonPathEntries(python_imports, module_space):
  parts = python_imports.split(':')
  return [module_space] + ['%s/%s' % (module_space, path) for path in parts]

def FindModuleSpace():
  """Finds the runfiles tree."""
  stub_filename = sys.argv[0]
  if not os.path.isabs(stub_filename):
    stub_filename = os.path.join(os.getcwd(), stub_filename)

  while True:
    module_space = stub_filename + ('.exe' if IsWindows() else '') + '.runfiles'
    if os.path.isdir(module_space):
      return module_space

    runfiles_pattern = r'(.*\.runfiles)' + (r'\\' if IsWindows() else '/') + '.*'
    matchobj = re.match(runfiles_pattern, stub_filename)
    if matchobj:
      return matchobj.group(1)

    if not os.path.islink(stub_filename):
      break
    target = os.readlink(stub_filename)
    if os.path.isabs(target):
      stub_filename = target
    else:
      stub_filename = os.path.join(os.path.dirname(stub_filename), target)

  raise AssertionError('Cannot find .runfiles directory for %s' % sys.argv[0])

def ExtractZip(zip_path, dest_dir):
  """Extracts the contents of a zip file, preserving the unix file mode bits.

  These include the permission bits, and in particular, the executable bit.

  Ideally the zipfile module should set these bits, but it doesn't. See:
  https://bugs.python.org/issue15795.

  Args:
      zip_path: The path to the zip file to extract
      dest_dir: The path to the destination directory
  """
  zip_path = GetWindowsPathWithUNCPrefix(zip_path)
  dest_dir = GetWindowsPathWithUNCPrefix(dest_dir)
  with zipfile.ZipFile(zip_path) as zf:
    for info in zf.infolist():
      zf.extract(info, dest_dir)
      # UNC-prefixed paths must be absolute/normalized. See
      # https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file#maximum-path-length-limitation
      file_path = os.path.abspath(os.path.join(dest_dir, info.filename))
      # The Unix st_mode bits (see "man 7 inode") are stored in the upper 16
      # bits of external_attr. Of those, we set the lower 12 bits, which are the
      # file mode bits (since the file type bits can't be set by chmod anyway).
      attrs = info.external_attr >> 16
      if attrs != 0:  # Rumor has it these can be 0 for zips created on Windows.
        os.chmod(file_path, attrs & 0o7777)

# Create the runfiles tree by extracting the zip file
def CreateModuleSpace():
  temp_dir = tempfile.mkdtemp('', 'Bazel.runfiles_')
  ExtractZip(os.path.dirname(__file__), temp_dir)
  return os.path.join(temp_dir, 'runfiles')

# Returns repository roots to add to the import path.
def GetRepositoriesImports(module_space, import_all):
  if import_all:
    repo_dirs = [os.path.join(module_space, d) for d in os.listdir(module_space)]
    return [d for d in repo_dirs if os.path.isdir(d)]
  return [os.path.join(module_space, '%workspace_name%')]

def RunfilesEnvvar(module_space):
  """Finds the runfiles manifest or the runfiles directory."""
  # If this binary is the data-dependency of another one, the other sets
  # RUNFILES_MANIFEST_FILE or RUNFILES_DIR for our sake.
  runfiles = os.environ.get('RUNFILES_MANIFEST_FILE', None)
  if runfiles:
    return ('RUNFILES_MANIFEST_FILE', runfiles)

  runfiles = os.environ.get('RUNFILES_DIR', None)
  if runfiles:
    return ('RUNFILES_DIR', runfiles)

  # If running from a zip, there's no manifest file.
  if IsRunningFromZip():
    return ('RUNFILES_DIR', module_space)

  # Look for the runfiles "output" manifest, argv[0] + ".runfiles_manifest"
  runfiles = module_space + '_manifest'
  if os.path.exists(runfiles):
    return ('RUNFILES_MANIFEST_FILE', runfiles)

  # Look for the runfiles "input" manifest, argv[0] + ".runfiles/MANIFEST"
  runfiles = os.path.join(module_space, 'MANIFEST')
  if os.path.exists(runfiles):
    return ('RUNFILES_DIR', runfiles)

  # If running in a sandbox and no environment variables are set, then
  # Look for the runfiles  next to the binary.
  if module_space.endswith('.runfiles') and os.path.isdir(module_space):
    return ('RUNFILES_DIR', module_space)

  return (None, None)

# TODO(#6443): Remove this once there's no longer a host configuration for
# Python targets to appear in.
def MaybeEmitHostVersionWarning(ret_code):
  """Warns the user if a failure may be due to the host config's version.

  This emits a message to stderr if
    1) ret_code is non-zero,
    2) the target was built in the host config and with toolchains enabled, and
    3) at analysis time we detected a mismatch between the host config's version
       and this target's explicitly declared version, or else this target did
       not explicitly declare its version. (The former diagnoses targets
       affected by #6443, and the latter diagnoses targets that are broken by
       fixing #4815.)

  See also #7899, #8549, and PyCommon#shouldWarnAboutHostVersionUponFailure.

  Since this warning is emitted here in the stub script and not in Bazel itself,
  it will be present in all failing runs of affected targets, even when executed
  directly and not via `bazel run`. However, note that this warning is never
  added to non-host-configured targets, and that it can be disabled by ensuring
  the correct Python version is passed to --host_force_python and declared in
  tools' python_version attributes.

  Args:
      ret_code: The exit code of the payload user program
  """
  if ret_code == 0:
    return
  if not %enable_host_version_warning%:
    return

  host_version = %python_version_from_config%
  target_version = %python_version_from_attr%
  opposite_of_host_version = '2' if host_version == '3' else '3'

  if %python_version_specified_explicitly%:
    # Mismatch with explicitly declared version.
    diagnostic = """\
Note: The failure of target {target} (with exit code {ret_code}) may have been \
caused by the fact that it is a Python {target_version} program that was built \
in the host configuration, which uses Python {host_version}. You can change \
the host configuration (for the entire build) to instead use Python \
{target_version} by setting --host_force_python=PY{target_version}.\
""".format(
    target='%target%',
    ret_code=ret_code,
    target_version=target_version,
    host_version=host_version)
  else:
    diagnostic = """\
Note: The failure of target {target} (with exit code {ret_code}) may have been \
caused by the fact that it is running under Python {host_version} instead of \
Python {opposite_of_host_version}. Examine the error to determine if that \
appears to be the problem. Since this target is built in the host \
configuration, the only way to change its version is to set \
--host_force_python=PY{opposite_of_host_version}, which affects the entire \
build.\
""".format(
    target='%target%',
    ret_code=ret_code,
    host_version=host_version,
    opposite_of_host_version=opposite_of_host_version)

  # TODO(brandjon): Change the wording "You are likely seeing this message
  # because" to something less strong after a few releases from 0.27. By that
  # point, migration for toolchains won't be the main reason this error is seen
  # by users.
  message = """\
----------------
{diagnostic}

If this error started occurring in Bazel 0.27 and later, it may be because the \
Python toolchain now enforces that targets analyzed as PY2 and PY3 run under a \
Python 2 and Python 3 interpreter, respectively. See \
https://github.com/bazelbuild/bazel/issues/7899 for more information.
----------------""".format(diagnostic=diagnostic)
  print(message, file=sys.stderr)

def Deduplicate(items):
  """Efficiently filter out duplicates, keeping the first element only."""
  return list(collections.OrderedDict((it, None) for it in items).keys())

def Main():
  args = sys.argv[1:]

  new_env = {}

  if IsRunningFromZip():
    module_space = CreateModuleSpace()
  else:
    module_space = FindModuleSpace()

  python_imports = '%imports%'
  python_path_entries = CreatePythonPathEntries(python_imports, module_space)
  python_path_entries += GetRepositoriesImports(module_space, %import_all%)
  # Remove duplicates to avoid overly long PYTHONPATH (#10977). Preserve order,
  # keep first occurrence only.
  python_path_entries = Deduplicate(python_path_entries)
  python_path_entries = [GetWindowsPathWithUNCPrefix(d) for d in python_path_entries]

  old_python_path = os.environ.get('PYTHONPATH')
  python_path = os.pathsep.join(python_path_entries)
  if old_python_path:
    python_path += os.pathsep + old_python_path

  if IsWindows():
    python_path = python_path.replace('/', os.sep)

  new_env['PYTHONPATH'] = python_path
  runfiles_envkey, runfiles_envvalue = RunfilesEnvvar(module_space)
  if runfiles_envkey:
    new_env[runfiles_envkey] = runfiles_envvalue

  # Now look for my main python source file.
  # The magic string percent-main-percent is replaced with the filename of the
  # main file of the Python binary in BazelPythonSemantics.java.
  rel_path = '%main%'
  if IsWindows():
    rel_path = rel_path.replace('/', os.sep)

  main_filename = os.path.join(module_space, rel_path)
  main_filename = GetWindowsPathWithUNCPrefix(main_filename)
  assert os.path.exists(main_filename), \
         'Cannot exec() %r: file not found.' % main_filename
  assert os.access(main_filename, os.R_OK), \
         'Cannot exec() %r: file not readable.' % main_filename

  program = python_program = FindPythonBinary(module_space)
  if python_program is None:
    raise AssertionError('Could not find python binary: ' + PYTHON_BINARY)

  cov_tool = os.environ.get('PYTHON_COVERAGE')
  if cov_tool:
    # Inhibit infinite recursion:
    del os.environ['PYTHON_COVERAGE']
    if not os.path.exists(cov_tool):
      raise EnvironmentError('Python coverage tool %s not found.' % cov_tool)
    args = [python_program, cov_tool, 'run', '-a', '--branch', main_filename] + args
    # coverage library expects sys.path[0] to contain the library, and replaces
    # it with the directory of the program it starts. Our actual sys.path[0] is
    # the runfiles directory, which must not be replaced.
    # CoverageScript.do_execute() undoes this sys.path[0] setting.
    #
    # Update sys.path such that python finds the coverage package. The coverage
    # entry point is coverage.coverage_main, so we need to do twice the dirname.
    new_env['PYTHONPATH'] = \
        new_env['PYTHONPATH'] + ':' + os.path.dirname(os.path.dirname(cov_tool))
    new_env['PYTHON_LCOV_FILE'] = os.environ.get('COVERAGE_DIR') + '/pylcov.dat'
  else:
    args = [python_program, main_filename] + args

  os.environ.update(new_env)

  try:
    sys.stdout.flush()
    if IsRunningFromZip():
      # If RUN_UNDER_RUNFILES equals 1, it means we need to
      # change directory to the right runfiles directory.
      # (So that the data files are accessible)
      if os.environ.get('RUN_UNDER_RUNFILES') == '1':
        os.chdir(os.path.join(module_space, '%workspace_name%'))
      ret_code = subprocess.call(args)
      shutil.rmtree(os.path.dirname(module_space), True)
      MaybeEmitHostVersionWarning(ret_code)
      sys.exit(ret_code)
    else:
      # On Windows, os.execv doesn't handle arguments with spaces correctly,
      # and it actually starts a subprocess just like subprocess.call.
      #
      # If we may need to emit a host config warning after execution, don't
      # execv because we need control to return here. This only happens for
      # targets built in the host config, so other targets still get to take
      # advantage of the performance benefits of execv.
      if IsWindows() or %enable_host_version_warning%:
        ret_code = subprocess.call(args)
        MaybeEmitHostVersionWarning(ret_code)
        sys.exit(ret_code)
      else:
        os.execv(args[0], args)
  except EnvironmentError:
    # This works from Python 2.4 all the way to 3.x.
    e = sys.exc_info()[1]
    # This exception occurs when os.execv() fails for some reason.
    if not getattr(e, 'filename', None):
      e.filename = program  # Add info to error message
    raise

if __name__ == '__main__':
  Main()
