# Copyright 2016 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.
"""Module to exec cc toolchain targets and extract contents for all configs."""

from __future__ import print_function

import atexit
import os
import shlex
import shutil
import subprocess
import tarfile

from util import get_autoconfig_target_name
from util import get_git_root

GIT_ROOT = get_git_root()
CONFIG_REPO = "local_config_cc"
CONFIG_FILES = ["CROSSTOOL", "BUILD", "cc_wrapper.sh", "dummy_toolchain.bzl"]
TMP_DIR = os.path.join(GIT_ROOT, "release", "tmp")


def _cleanup():
  """Cleanup generated files."""
  if os.path.exists(TMP_DIR):
    shutil.rmtree(TMP_DIR)


def execute_and_extract_configs(container_configs_list, bazel_version):
  """Executes the docker_toolchain_autoconfig targets and extract configs.

  If configs already exist in this repo, the script will delete them and
  generate new ones.

  It generate cc configs which currently includes: CROSSTOOL, BUILD,
  cc_wrapper.sh and dummy_toolchain.bzl. Examples can be found in
  configs/ubuntu16_04_clang/1.0/bazel_0.15.0/default/.

  There is one such set of cc configs per container per Bazel version per config
  type.

  Args:
    container_configs_list: list of ContainerConfigs, the list of
      ContainerConfigs to generate configs for.
    bazel_version: string, the version of Bazel used to generate the configs.
  """

  atexit.register(_cleanup)

  # Create temporary directory to store generated tarballs of configs.
  if os.path.exists(TMP_DIR):
    shutil.rmtree(TMP_DIR)
  os.makedirs(TMP_DIR)

  for container_configs in container_configs_list:
    for config in container_configs.configs:

      # Get target basename from config definitions.
      target = get_autoconfig_target_name(
          config_type=config.config_type,
          distro=container_configs.distro,
          config_version=container_configs.version,
          bazel_version=bazel_version)

      # Remove old config dir if exists.
      if os.path.exists(config.get_config_dir()):
        print("\nOld version of toolchain configs for {target} already exists. "
              "Deleting and generating again.".format(target=target))
        shutil.rmtree(config.get_config_dir())

      # Generate config directory.
      os.makedirs(config.get_config_dir())

      command = ("bazel build //{PACKAGE}:{TARGET}").format(
          PACKAGE=container_configs.package, TARGET=target)
      print("\nExecuting command: %s\n" % command)
      subprocess.check_call(shlex.split(command))

      command = (
          "cp "
          "{GIT_ROOT}/bazel-out/k8-fastbuild/bin/{PACKAGE}/{TARGET}_outputs.tar"
          " {OUTPUT_DIR}/").format(
              GIT_ROOT=GIT_ROOT,
              OUTPUT_DIR=TMP_DIR,
              PACKAGE=container_configs.package,
              TARGET=target)
      print("\nExecuting command: %s\n" % command)
      subprocess.check_call(shlex.split(command))

      # Extract toolchain configs.
      tar_path = os.path.join(TMP_DIR, "%s_outputs.tar" % target)
      tar = tarfile.open(tar_path)

      for config_file in CONFIG_FILES:
        # Extract toolchain config without the CONFIG_REPO name.
        member = tar.getmember(os.path.join(CONFIG_REPO, config_file))
        member.name = os.path.basename(member.name)
        tar.extract(member, config.get_config_dir())
