# 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 ./bazel-out/k8-fastbuild/bin/{PACKAGE}/{TARGET}_outputs.tar "
                 "{OUTPUT_DIR}/").format(
                     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())
