#!/usr/bin/env python3

# Copyright 2020 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.
"""Manages IREE Docker image definitions.

Includes information on their dependency graph and GCR URL.

See the README for more information on how to add and update images.

Example usage:

Rebuild the cmake image and all images that transitively on depend on it,
tagging them with `latest` and updating all references to their sha digests:
  python3 build_tools/docker/manage_images.py --image cmake

Print out output for rebuilding the cmake image and all images that
transitively on depend on it, but don't take side-effecting actions:
  python3 build_tools/docker/manage_images.py --image cmake --dry-run

Rebuild and push all images and update references to them in the repository:
  python3 build_tools/docker/manage_images.py --images all
"""

import argparse
import fileinput
import os
import posixpath
import re
import subprocess
import sys
from typing import Dict, List, Sequence, Union

import utils

IREE_GCR_URL = 'gcr.io/iree-oss/'
DIGEST_REGEX = r'sha256:[a-zA-Z0-9]+'
DOCKER_DIR = 'build_tools/docker/'.replace('/', os.sep)

# Map from image names to images that they depend on.
IMAGES_TO_DEPENDENCIES = {
    'base': [],
    'bazel': ['base', 'util'],
    'cmake': ['base', 'util'],
    'cmake-android': ['cmake', 'util'],
    'cmake-python': ['cmake'],
    'cmake-python-vulkan': ['cmake-python', 'vulkan'],
    'cmake-python-swiftshader': ['cmake-python-vulkan', 'swiftshader'],
    'cmake-python-nvidia': ['cmake-python-vulkan'],
    'cmake-bazel-frontends': ['cmake-python', 'bazel'],
    'cmake-bazel-frontends-vulkan': ['cmake-bazel-frontends', 'vulkan'],
    'cmake-bazel-frontends-swiftshader': [
        'cmake-bazel-frontends-vulkan', 'swiftshader'
    ],
    'cmake-bazel-frontends-nvidia': ['cmake-bazel-frontends-vulkan'],
    'rbe-toolchain': ['vulkan'],
    'swiftshader': ['cmake'],
    'util': [],
    'vulkan': ['util'],
}

IMAGES_TO_DEPENDENT_IMAGES = {k: [] for k in IMAGES_TO_DEPENDENCIES}
for image, dependencies in IMAGES_TO_DEPENDENCIES.items():
  for dependency in dependencies:
    IMAGES_TO_DEPENDENT_IMAGES[dependency].append(image)

IMAGES_HELP = [f'`{name}`' for name in IMAGES_TO_DEPENDENCIES]
IMAGES_HELP = f'{", ".join(IMAGES_HELP)} or `all`'


def parse_arguments():
  """Parses command-line options."""
  parser = argparse.ArgumentParser(
      description="Build IREE's Docker images and optionally push them to GCR.")
  parser.add_argument('--images',
                      '--image',
                      type=str,
                      required=True,
                      action='append',
                      help=f'Name of the image to build: {IMAGES_HELP}.')
  parser.add_argument(
      '--dry_run',
      '--dry-run',
      '-n',
      action='store_true',
      help='Print output without building or pushing any images.')

  args = parser.parse_args()
  for image in args.images:
    if image == 'all':
      # Sort for a determinstic order
      args.images = sorted(IMAGES_TO_DEPENDENCIES.keys())
    elif image not in IMAGES_TO_DEPENDENCIES:
      raise parser.error('Expected --image to be one of:\n'
                         f'  {IMAGES_HELP}\n'
                         f'but got `{image}`.')
  return args


def _dag_dfs(input_nodes: Sequence[str],
             node_to_child_nodes: Dict[str, Sequence[str]]) -> List[str]:
  # Python doesn't have a builtin OrderedSet, but we don't have many images, so
  # we just use a list.
  ordered_nodes = []

  def add_children(parent_node: str):
    if parent_node not in ordered_nodes:
      for child_node in node_to_child_nodes[parent_node]:
        add_children(child_node)
      ordered_nodes.append(parent_node)

  for node in input_nodes:
    add_children(node)
  return ordered_nodes


def get_ordered_images_to_process(images: Sequence[str]) -> List[str]:
  dependents = _dag_dfs(images, IMAGES_TO_DEPENDENT_IMAGES)
  dependents.reverse()
  return dependents


def get_dependencies(images: Sequence[str]) -> List[str]:
  return _dag_dfs(images, IMAGES_TO_DEPENDENCIES)


def get_repo_digest(tagged_image_url: str, dry_run: bool = False) -> str:
  inspect_command = [
      'docker',
      'image',
      'inspect',
      tagged_image_url,
      '-f',
      '{{index .RepoDigests 0}}',
  ]
  try:
    completed_process = utils.run_command(
        inspect_command,
        dry_run=False,  # Run even if --dry_run is True.
        capture_output=True,
        timeout=10)
  except subprocess.CalledProcessError as error:
    if dry_run:
      return ""
    else:
      raise RuntimeError(
          f'Computing the repository digest for {tagged_image_url} failed. Has '
          'it been pushed to GCR?') from error
  _, repo_digest = completed_process.stdout.strip().split('@')
  return repo_digest


def update_rbe_reference(digest: str, dry_run: bool = False):
  print('Updating WORKSPACE file for rbe-toolchain')
  digest_updates = 0
  for line in fileinput.input(files=['WORKSPACE'], inplace=True):
    if line.strip().startswith('digest ='):
      digest_updates += 1
      if dry_run:
        print(line, end='')
      else:
        print(re.sub(DIGEST_REGEX, digest, line), end='')
    else:
      print(line, end='')

  if digest_updates > 1:
    raise RuntimeError(
        "There is more than one instance of 'digest =' in the WORKSPACE file. "
        "This means that more than just the 'rbe_toolchain' digest was "
        "overwritten, and the file should be restored.")


def update_references(image_url: str, digest: str, dry_run: bool = False):
  """Updates all references to 'image_url' with a sha256 digest."""
  print(f'Updating references to {image_url}')

  grep_command = ['git', 'grep', '-l', f'{image_url}@sha256']
  try:
    completed_process = utils.run_command(grep_command,
                                          capture_output=True,
                                          timeout=5)
  except subprocess.CalledProcessError as error:
    if error.returncode == 1:
      print(f'Found no references to {image_url}')
      return
    raise error

  # Update references in all grepped files.
  files = completed_process.stdout.split()
  print(f'Updating references in {len(files)} files: {files}')
  if not dry_run:
    for line in fileinput.input(files=files, inplace=True):
      print(re.sub(f'{image_url}@{DIGEST_REGEX}', f'{image_url}@{digest}',
                   line),
            end='')


def parse_prod_digests() -> Dict[str, str]:
  image_urls_to_prod_digests = {}
  with open(utils.PROD_DIGESTS_PATH, "r") as f:
    for line in f:
      image_url, digest = line.strip().split("@")
      image_urls_to_prod_digests[image_url] = digest
  return image_urls_to_prod_digests


if __name__ == '__main__':
  args = parse_arguments()

  # Ensure the user has the correct authorization to push to GCR.
  utils.check_gcloud_auth(dry_run=args.dry_run)

  images_to_process = get_ordered_images_to_process(args.images)
  print(f'Also processing dependent images. Will process: {images_to_process}')

  dependencies = get_dependencies(images_to_process)
  print(f'Pulling image dependencies: {dependencies}')
  image_urls_to_prod_digests = parse_prod_digests()
  for dependency in dependencies:
    dependency_url = posixpath.join(IREE_GCR_URL, dependency)
    # If `dependency` is a new image then it may not have a prod digest yet.
    if dependency_url in image_urls_to_prod_digests:
      digest = image_urls_to_prod_digests[dependency_url]
      dependency_with_digest = f'{dependency_url}@{digest}'
      utils.run_command(["docker", "pull", dependency_with_digest],
                        dry_run=args.dry_run)

  for image in images_to_process:
    print('\n' * 5 + f'Processing image {image}')
    image_url = posixpath.join(IREE_GCR_URL, image)
    tagged_image_url = f'{image_url}'
    image_path = os.path.join(DOCKER_DIR, image)

    utils.run_command(
        ['docker', 'build', '--tag', tagged_image_url, image_path],
        dry_run=args.dry_run)

    utils.run_command(['docker', 'push', tagged_image_url],
                      dry_run=args.dry_run)

    digest = get_repo_digest(tagged_image_url, args.dry_run)

    # Check that the image is in 'prod_digests.txt' and append it to the list
    # in the file if it isn't.
    if image_url not in image_urls_to_prod_digests:
      image_with_digest = f'{image_url}@{digest}'
      print(
          f'Adding new image {image_with_digest} to {utils.PROD_DIGESTS_PATH}')
      if not args.dry_run:
        with open(utils.PROD_DIGESTS_PATH, 'a') as f:
          f.write(f'{image_with_digest}\n')

    # Just hardcode this oddity
    if image == 'rbe-toolchain':
      update_rbe_reference(digest, dry_run=args.dry_run)
    update_references(image_url, digest, dry_run=args.dry_run)
