# 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.
"""Data structures of toolchain configs."""

import os


class ContainerConfigs(object):
  """Group of configs that are generated using the same container.

  Attributes:
    distro: string, base distro of container used to generate configs.
    version: string, version of the configs.
    image: string, the container registry entry of the image used to
      generated the configs, e.g. gcr.io/cloud-marketplace/google/clang-ubuntu.
    package: string, the Bazel package in which we will generate the target to
      build configs.
    platform_target: string, the platform target name of the corresponding RBE
      container these configs will be used together with, e.g. rbe_ubuntu1604.
      This is required to set value for flags:
         --extra_execution_platforms, --host_platform and --platforms.
        (Platform: https://docs.bazel.build/versions/master/platforms.html)
    constraints: string, additional toolchain constraints needed for the cpp
      toolchain definition.
      These must be valid targets in this repo or @bazel_tools.
      (Toolchain: https://docs.bazel.build/versions/master/toolchains.html)
    configs: list of Config object, a list of configs for each supported types
      generated using the container specified in the current ContainerConfig.
  """

  # Currently supported distros.
  _SUPPORTED_DISTROS = ["debian8", "ubuntu16_04"]

  # Map from the container distro to additional pre-defined cpp toolchain
  # definition constraints.
  _DISTRO_CONSTRAINTS_MAP = {
      "debian8": ["//constraints:jessie"],
      "ubuntu16_04": ["//constraints:xenial"]
  }

  def __init__(self, distro, version, image, package, config_types,
               platform_target, git_root, bazel_version):
    """Inits ContainerConfigs.

    Args:
      distro: string, base distro of container used to generate configs.
      version: string, version of the configs.
      image: string, the container registry entry of the image used to
        generated the configs, e.g.
        gcr.io/cloud-marketplace/google/clang-ubuntu.
      package: string, the Bazel package in which we will generate the target to
      build configs.
      config_types: types of config to generated with this container, e.g.
        default, msan.
      platform_target: string, the platform target name of the corresponding RBE
        container these configs will be used together with  e.g. rbe_ubuntu1604.
        This is required to set value for flags:
          --extra_execution_platforms, --host_platform and --platforms.
          (Platform: https://docs.bazel.build/versions/master/platforms.html)
      git_root: the absolute path of the root directory of the current
        repository.
      bazel_version: the version of Bazel used to generated the configs.

    Returns:
      A ContainerConfigs object.
    Raises:
      ValueError: An error occurred when input distro is not supported.
    """

    # Validate distro is supported.
    if distro not in ContainerConfigs._SUPPORTED_DISTROS:
      raise ValueError(
          "Input distro: %s is not supported. Supported distros are %s" %
          (distro, " ".join(ContainerConfigs._SUPPORTED_DISTROS)))

    self._git_root = git_root
    self._bazel_version = bazel_version

    self.distro = distro
    self.version = version
    self.image = image
    self.package = package
    self.platform_target = platform_target
    self.constraints = ContainerConfigs._DISTRO_CONSTRAINTS_MAP[distro]

    self.configs = [
        Config(root=self._get_config_base_dir(), config_type=config_type)
        for config_type in config_types
    ]

  def get_target_build_path(self):
    """Returns the absolute path of the target BUILD file."""
    return os.path.join(self._git_root, self.package, "BUILD")

  def get_toolchain_bazelrc_path(self):
    """Returns the absolute path of the toolchain.bazelrc file."""
    return os.path.join(self._git_root, self.package, self.version,
                        "toolchain.bazelrc")

  def get_platform_build_path(self):
    """Returns the absolute path of BUILD file with platform definition."""
    return os.path.join(self._git_root, self.package, self.version, "BUILD")

  def get_java_runtime_build_path(self):
    """Returns the absolute path of BUILD file with java runtime."""
    return self.get_platform_build_path()

  def get_cpp_build_path(self):
    """Returns the absolute path of BUILD file with cpp toolchain definition."""
    return os.path.join(self._get_config_base_dir(), "cpp", "BUILD")

  def _get_config_base_dir(self):
    """Returns the absolute path of bazel_{version} directory.

    This returns the absolute path of bazel_{version} directory where configs
    are stored in the bazel-toolchains repo.

    For example: /.../configs/ubuntu16_04_clang/1.0/bazel_0.15.0/
    """
    return os.path.join(self._git_root, self.package, self.version,
                        "bazel_%s" % self._bazel_version)


class Config(object):
  """Configs of a single type that are generated using a container.

  Attributes:
    config_type: string, type of the configs, e.g. default, msan.
    constraints: string, additional toolchain constraints needed for the cpp
      toolchain definition.
      These must be valid targets in this repo or @bazel_tools.
      (Toolchain: https://docs.bazel.build/versions/master/toolchains.html)
  """

  # Currently supported config types.
  _SUPPORTED_CONFIG_TYPES = ["default", "msan"]

  # Map from the config type to additional pre-defined cpp toolchain
  # definition constraints.
  _TYPE_CONSTRAINTS_MAP = {
      "default": [],
      "msan": ["//constraints/sanitizers:support_msan"]
  }

  def __init__(self, root, config_type):
    """Inits Config.

    Args:
      root: string, absolute path to the bazel_{version} directory, e.g.
        /.../configs/ubuntu16_04_clang/1.0/bazel_0.15.0/.
      config_type: string, type of the configs.

    Returns:
      A Config object.
    Raises:
      ValueError: An error occurred when input config type is not supported.
    """

    # Validate config_type is supported.
    if config_type not in Config._SUPPORTED_CONFIG_TYPES:
      raise ValueError(
          "Input config type: %s is not supported. Supported types are %s" %
          (config_type, " ".join(Config._SUPPORTED_CONFIG_TYPES)))

    self._root = root
    self.config_type = config_type
    self.constraints = Config._TYPE_CONSTRAINTS_MAP[config_type]

  def get_config_dir(self):
    """Returns the absolute path of the cc toolchain configs directory."""
    return os.path.join(self._root, self.config_type)

  def get_metadata_path(self):
    """Returns the absolute path of the METADATA file."""
    return os.path.join(self.get_config_dir(), "METADATA")
