#!/usr/bin/env python3
# Copyright 2019 Google LLC
#
# 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
#
#      https://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.

# Usage:
#   python3 build_tools/scripts/start_colab_kernel.py
#
# Note that in the case that multiple python interpreters are present on
# your path, it is best to not risk it: use an explicit one.
#
# This will build the python bindings and start a colab kernel with them
# on the path. It takes some care to ensure that the build is running with
# the same python interpreter as is used to launch this script.
#
# Pre-requisites:
# Install Jupyter (from https://jupyter.org/install)
#   python3 -m pip install --upgrade pip
#   python3 -m pip install jupyter
# Setup colab (https://research.google.com/colaboratory/local-runtimes.html)
#   python3 -m pip install jupyter_http_over_ws
#   jupyter serverextension enable --py jupyter_http_over_ws
# If you plan on using TensorFlow, enable the TensorFlow parts of IREE's
# compiler by adding a define to your user.bazelrc file:
#   build --define=iree_tensorflow=true

import os
import subprocess
import shutil
import sys

repo_root = None
bazel_env = dict(os.environ)
bazel_bin = None
bazel_exe = None


def setup_environment():
  """Sets up some environment globals."""
  global bazel_bin
  global repo_root
  global bazel_exe

  # Determine the repository root (two dir-levels up).
  repo_root = os.path.dirname(
      os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  print("Repository root: %s" % (repo_root,))

  # Use 'bazelisk' instead of 'bazel' if it exists on the path.
  # Bazelisk is an optional utility that pick versions of Bazel to use and
  # passes through all command-line arguments to the real Bazel binary:
  # https://github.com/bazelbuild/bazelisk
  bazel_exe = "bazelisk" if shutil.which("bazelisk") else "bazel"
  print("Using bazel executable: %s" % (bazel_exe))

  # Detect python and query bazel for its output.
  print("Setting Bazel PYTHON_BIN=%s" % (sys.executable,))
  bazel_env["PYTHON_BIN"] = sys.executable
  bazel_bin = subprocess.check_output([bazel_exe, "info", "bazel-bin"],
                                      cwd=repo_root,
                                      env=bazel_env).decode("utf-8")
  bazel_bin = bazel_bin.splitlines()[0]
  # Bazel always reports the path with '/'. On windows, switch it
  # since we need native path manipulation code below to have it the
  # right way.
  if os.path.sep == "\\":
    bazel_bin = bazel_bin.replace("/", "\\")
  print("Found Bazel bin: %s" % (bazel_bin))


def build():
  """Builds the python bundle."""
  print("Building python bindings...")
  subprocess.check_call(
      [bazel_exe, "build", "//bindings/python/pyiree:everything_for_colab"],
      cwd=repo_root,
      env=bazel_env)


def run():
  """Runs the Jupyter notebook."""
  runfiles_suffix = ".runfiles"
  if os.path.sep == "\\":
    runfiles_suffix = ".exe.runfiles"  # Windows uses a special name

  runfiles_dir = os.path.join(bazel_bin, "bindings", "python", "pyiree",
                              "everything_for_colab" + runfiles_suffix)
  # Top level directories under the runfiles get added to the sys path.
  extra_python_path = []
  # The iree_core/bindings/python directory under runfiles needs to come
  # first on the path.
  extra_python_path.append(
      os.path.join(runfiles_dir, "iree_core", "bindings", "python"))
  for python_module in os.listdir(runfiles_dir):
    python_module_path = os.path.join(runfiles_dir, python_module)
    if os.path.isdir(python_module_path):
      extra_python_path.append(python_module_path)

  print("Augmented Python sys.path:")
  for p in extra_python_path:
    print(" ", p)
  launch_jupyter(extra_python_path)


def launch_jupyter(python_path):
  """Launches Jupyter with a python path."""
  try:
    from jupyter_core.command import main as jupyter_main  # pylint: disable=g-import-not-at-top
  except ImportError:
    show_install_instructions()
    sys.exit(1)

  # Override the PYTHONPATH, which Jupyter propagates to its kernels.
  path_sep = ":"
  if os.path.sep == "\\":
    path_sep = ";"  # Windows
  os.environ["PYTHONPATH"] = path_sep.join(python_path)

  # Launch jupyter (this is all the "jupyter" shell command does).
  sys.argv = [
      "jupyter", "notebook",
      "--NotebookApp.allow_origin='https://colab.research.google.com'",
      "--port=8888", "--NotebookApp.port_retries=0"
  ]
  sys.exit(jupyter_main())


def show_install_instructions():
  """Prints some install instructions."""
  print("ERROR: Unable to load Jupyter. Ensure that it is installed:")
  print("  %s -m pip install --upgrade pip" % (sys.executable,))
  print("  %s -m pip install jupyter" % (sys.executable,))
  print("  %s -m pip install jupyter_http_over_ws" % (sys.executable,))
  print("  jupyter serverextension enable --py jupyter_http_over_ws")


if __name__ == "__main__":
  setup_environment()
  build()
  run()
