#!/usr/bin/python
"""Runs the bazel executable for the platform, passing args along."""

import os
import os.path
import re
import subprocess
import sys
import multiprocessing


def main():
  workspace = find_workspace(os.path.dirname(os.path.realpath(__file__)))
  if not workspace:
    sys.exit('Must run %s within a workspace.' % os.path.basename(sys.argv[0]))
  if sys.platform.startswith('linux'):
    platform = 'linux-x86_64'
    jdk_subdir = 'linux'
    config = 'linux'
  elif sys.platform == 'darwin':
    platform = 'darwin-x86_64'
    jdk_subdir = os.path.join('mac', 'Contents', 'Home')
    config = 'darwin'
  elif sys.platform == 'win32':
    platform = 'windows-x86_64'
    jdk_subdir = 'win64'
    config = 'windows'
  else:
    sys.exit('Platform %s is not yet supported.' % sys.platform)

  bazel = os.path.join(workspace, 'prebuilts', 'tools', platform, 'bazel',
                       'bazel-real')
  args = sys.argv[1:]
  command = bazel_command(args)

  env = {}
  env['JAVA_HOME'] = os.path.join(workspace, 'prebuilts', 'studio', 'jdk', jdk_subdir)
  env['ANDROID_NDK_HOME'] = os.path.join(workspace, 'prebuilts', 'studio', 'sdk', config, 'ndk-bundle')
  env['TERM'] = os.environ.get('TERM', '')
  env['SHELL'] = os.environ.get('SHELL', '')
  env['HOME'] = os.environ.get('HOME', '')
  if 'QA_ANDROID_SDK_ROOT' in os.environ:
    env['QA_ANDROID_SDK_ROOT'] = os.environ['QA_ANDROID_SDK_ROOT']
  if sys.platform == 'darwin':
    args.insert(0, '--watchfs')
    if not os.path.exists('/Library/Developer/CommandLineTools'):
      print('/Library/Developer/CommandLineTools does not exist. Please install it with '
            'xcode-select --install')
      sys.exit(1)
    # This is needed for bazel to set itself up, even though we aren't using gcc.
    env['CC'] = os.environ.get('GCC', '/usr/bin/gcc')
  elif sys.platform == 'win32':
    # We don't need the tools to be installed locally if you're building remotely.
    # This isn't really the correct check, since --config=remote is just an alias for a bunch of other
    # settings. But in practice that's how you get into remote mode, so it should be good enough for now
    # at least.
    if (command in ['build', 'test'] and
        (not '--config=remote' in args and not '--config=dynamic' in args)):
      if (not os.path.exists('C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.26.28801') or
              not os.path.exists('C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0')):
        print('You must have MSVC Buildtools version 14.26.28801 and Windows SDK 10.0.18362.0 installed.\n'
              'An installer for these is available at go/studio-msvc-tools.')
        sys.exit(1)

    define_env(env, 'BAZEL_SH', 'C:\\tools\\msys64\\usr\\bin\\bash.exe',
        '***NOTE***: Bazel for Windows currently hardcodes "C:\\tools\\msys64", but we\n' +
        'could not find an installation of msys at this path on your machine.\n' +
        'Move your installation there if you already have it or\n' +
        'install it there from http://www.msys2.org.\n' +
        'Make sure to change the path to C:\\tools\\msys64\n' +
        '\n' +
        'See also: https://github.com/bazelbuild/bazel/issues/2447')
    # Bazel for windows requires a couple of extra env vars be set
    # SYSTEMROOT must be defined to run a win .exe; otherwise, subprocess.call
    # will hang.
    env['SYSTEMROOT'] = 'C:\\Windows'
    env['TMP'] = os.environ.get('TMP','')
    env['PATH'] = os.environ.get('PATH','')
    env['USERPROFILE'] = os.environ.get('USERPROFILE', '')

  else: # Linux
    env['CC'] = os.environ.get('GCC', '/usr/bin/gcc')


  if command == 'info' and bazel_command_index(args) == len(args) - 1:
    print("bazel-cpu-count: " + str(count_bazel_CPUs()))

  bazelrc_arg = '--bazelrc=%s' % os.path.join(workspace, 'tools',
                                              'base', 'bazel',
                                              config + '.bazel.rc')
  sys.exit(subprocess.call([bazel, bazelrc_arg] + args, env=env))


def define_env(env, var, value, msg=None):
  prev = os.environ.get(var)
  if prev:
    if not os.path.exists(value):
      print('{} is set to {}, but it does not exist'.format(var, value))
      sys.exit(1)
    env[var] = prev
  elif os.path.exists(value):
    env[var] = value
  else:
    print('Cannot find {} while trying to set "{}"'.format(value, var))
    if msg:
      print(msg)
    else:
      print('Make sure {} exists, or set "{}" manually to the correct value.'.format(value, var))
    sys.exit(1)


def find_workspace(path):
  if os.path.isfile(os.path.join(path, 'WORKSPACE')):
    return path
  else:
    parent = os.path.dirname(path)
    return None if parent == path else find_workspace(parent)


"""
Returns the command index, which is the first non-option argument.
https://bazel.build/versions/master/docs/command-line-reference.html
"""
def bazel_command_index(args):
  for i in range(len(args)):
    if not args[i].startswith('-'):
      return i
  return None

"""
Returns the command itself, or None if not defined.
"""
def bazel_command(args):
  index = bazel_command_index(args)
  if index is None:
    return None
  return args[index]


"""
Calculates the CPU count like bazel. Only used for
information purposes. See:
https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/actions/LocalHostCapacity.java#L39
"""
def count_bazel_CPUs():
  if sys.platform == 'darwin':
    logical = int(os.popen2("sysctl -n hw.logicalcpu")[1].read())
    physical = int(os.popen2("sysctl -n hw.physicalcpu")[1].read())
  elif sys.platform == 'win32':
    logical = physical = multiprocessing.cpu_count()
  else: # Linux
    logical = int(os.popen2("cat /proc/cpuinfo | grep \"^processor\" | wc -l")[1].read())
    cpu_count = int(os.popen2("cat /proc/cpuinfo | grep \"^physical id\" | sort -u | wc -l")[1].read())
    core_count = int(os.popen2("cat /proc/cpuinfo | grep \"^core id\" | sort -u | wc -l")[1].read())
    physical = (cpu_count if cpu_count else logical) * (core_count if core_count else 1)

  hyperthreading = (logical != physical);
  return logical * (0.6 if hyperthreading else 1.0)

if __name__ == '__main__':
  main()
