# Copyright 2017 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.
"""packages.bzl contains definitions of functions that return packages.

Uses package_names.bzl to resolve packages needed for
tools installed in different containers.
"""

load(
    "@jessie_ca_certs_package_bundle//file:packages.bzl",
    ca_certs_packages = "packages",
)
load(
    "@jessie_package_bundle//file:packages.bzl",
    jessie_packages="packages",
)
load(
    "@trusty_package_bundle//file:packages.bzl",
    trusty_packages="packages",
)
load(
    "@xenial_package_bundle//file:packages.bzl",
    xenial_packages="packages",
)
load(
    ":package_names.bzl",
    "tool_names",
    "jessie_tools",
)


def get_jessie_packages(pkg_list):
  """Common function for getting jessie packages."""
  return [jessie_packages[p] for p in pkg_list]


def get_trusty_packages(pkg_list):
  """Common function for getting trusty packages."""
  return [trusty_packages[p] for p in pkg_list]


def get_xenial_packages(pkg_list):
  """Common function for getting xenial packages."""
  return [xenial_packages[p] for p in pkg_list]


def base_layer_packages():
  """Base packages for fully loaded toolchain."""
  base_tools = [
      tool_names.binutils,
      tool_names.curl,
      tool_names.ed,
      tool_names.file,
      tool_names.git,
      tool_names.openssh_client,
      tool_names.wget,
      tool_names.zip,
  ]
  packages = []
  for tool in base_tools:
    packages.extend(get_jessie_packages(jessie_tools()[tool]))
  return depset(packages).to_list()


def clang_layer_packages():
  """Packages for the clang layer."""
  clang_tools = [
      tool_names.binutils,
      tool_names.lib_cpp,
  ]
  packages = []
  for tool in clang_tools:
    packages.extend(get_jessie_packages(jessie_tools()[tool]))
  return depset(packages).to_list()


def python_layer_packages():
  """Packages for the python layer."""
  python_tools = [
      tool_names.python_dev,
      tool_names.python_numpy,
      tool_names.python_pip,
      tool_names.python3_dev,
      tool_names.python3_numpy,
      tool_names.python3_pip,
  ]
  packages = []
  for tool in python_tools:
    packages.extend(get_jessie_packages(jessie_tools()[tool]))
  return depset(packages).to_list()


def java_layer_packages():
  """Packages for the java layer."""
  java_tools = [
      tool_names.java_no_ca_certs,
  ]
  packages = []
  for tool in java_tools:
    packages.extend(get_jessie_packages(jessie_tools()[tool]))
  packages.append(ca_certs_packages["ca-certificates-java"])
  return depset(packages).to_list()
