// Copyright 2018 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.
package com.google.devtools.build.lib.rules.cpp;

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.util.StringUtil;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import javax.annotation.Nullable;

/**
 * Utils class for logic responsible for selecting a CToolchain from the CROSSTOOL file given the
 * cc_toolchain.
 */
public class CToolchainSelectionUtils {

  /**
   * Do-it-all CToolchain selection method that considers toolchain identifiers, cpu/compiler
   * attributes, and cpu/compiler options. Returns the CToolchain from the CROSSTOOL. If you need to
   * call anything else than this, you're holding it wrong.
   *
   * @param identifierAttribute value of the cc_toolchain.toolchain_identifier attribute
   * @param cpuAttribute value of the cc_toolchain.cpu attribute
   * @param compilerAttribute value of the cc_toolchain.compiler attribute
   * @param cpuOption value of the --cpu option
   * @param compilerOption value of the --compiler option
   * @param proto content of the CROSSTOOL file
   * @return selected CToolchain or throws InvalidConfigurationException when not found. Never
   *     returns null.
   */
  static CToolchain selectCToolchain(
      @Nullable String identifierAttribute,
      @Nullable String cpuAttribute,
      @Nullable String compilerAttribute,
      String cpuOption,
      @Nullable String compilerOption,
      CrosstoolRelease proto)
      throws InvalidConfigurationException {
    String identifierAttributeOrNull = StringUtil.emptyToNull(identifierAttribute);
    String cpuAttributeOrNull = StringUtil.emptyToNull(cpuAttribute);
    String compilerAttributeOrNull = StringUtil.emptyToNull(compilerAttribute);

    Preconditions.checkNotNull(cpuOption);
    String compilerOptionOrNull = StringUtil.emptyToNull(compilerOption);

    return selectCToolchainNoEmptyStrings(
        identifierAttributeOrNull,
        cpuAttributeOrNull,
        compilerAttributeOrNull,
        cpuOption,
        compilerOptionOrNull,
        proto);
  }

  private static CToolchain selectCToolchainNoEmptyStrings(
      String identifierAttribute,
      String cpuAttribute,
      String compilerAttribute,
      String cpuOption,
      String compilerOption,
      CrosstoolRelease proto)
      throws InvalidConfigurationException {
    CToolchain cToolchain = null;
    // Use the identifier to find the CToolchain from the CROSSTOOL (this is the way how
    // cc_toolchain will select CToolchain in the happy future, since it works with platforms).
    if (identifierAttribute != null) {
      cToolchain = getToolchainByIdentifier(proto, identifierAttribute);
    }
    if (cToolchain == null && cpuAttribute != null) {
      // Let's try to select the CToolchain using cpu and compiler rule attributes (the semi-new
      // way, compatible with platforms).
      try {
        cToolchain =
            selectToolchainUsingCpuAndMaybeCompiler(
                proto, new CrosstoolConfigurationIdentifier(cpuAttribute, compilerAttribute));
      } catch (InvalidConfigurationException e) {
        // We couldn't find the CToolchain using attributes, let's catch the exception and try
        // with options. It's safe to ignore the exception here, since if it was caused by
        // something else than the selection, it will be re-thrown below.
      }
    }
    if (cToolchain == null) {
      // We couldn't find the CToolchain using cpu and compiler attributes, let's try to select
      // it using --cpu/--compiler options (the legacy way, doesn't work with platforms).
      cToolchain =
          selectToolchainUsingCpuAndMaybeCompiler(
              proto, new CrosstoolConfigurationIdentifier(cpuOption, compilerOption));
    }
    return cToolchain;
  }

  /**
   * Selects a crosstool toolchain based on the toolchain identifier.
   *
   * @throws InvalidConfigurationException if no matching toolchain can be found, or if multiple
   *     toolchains with the same identifier are found.
   */
  private static CToolchain getToolchainByIdentifier(
      CrosstoolRelease proto, String toolchainIdentifier) throws InvalidConfigurationException {
    checkToolchain(toolchainIdentifier);
    CToolchain selectedToolchain = null;
    for (CToolchain toolchain : proto.getToolchainList()) {
      if (toolchain.getToolchainIdentifier().equals(toolchainIdentifier)) {
        if (selectedToolchain != null) {
          throw new InvalidConfigurationException(
              String.format("Multiple toolchains with '%s' identifier", toolchainIdentifier));
        }
        selectedToolchain = toolchain;
      }
    }
    if (selectedToolchain == null) {
      throw new InvalidConfigurationException(
          String.format("Toolchain identifier '%s' was not found", toolchainIdentifier));
    }
    return selectedToolchain;
  }

  /**
   * Makes sure that {@code selectedIdentifier} is a valid identifier for a toolchain, i.e. it
   * starts with a letter or an underscore and continues with only dots, dashes, spaces, letters,
   * digits or underscores (i.e. matches the following regular expression: "[a-zA-Z_][\.\- \w]*").
   *
   * @throws InvalidConfigurationException if selectedIdentifier does not match the aforementioned
   *     regular expression.
   */
  private static void checkToolchain(String selectedIdentifier)
      throws InvalidConfigurationException {
    // If you update this regex, please do so in the javadoc comment too, and also in the
    // crosstool_config.proto file.
    String rx = "[a-zA-Z_][\\.\\- \\w]*";
    if (!selectedIdentifier.matches(rx)) {
      throw new InvalidConfigurationException(
          String.format(
              "Toolchain identifier '%s' is illegal (does not match '%s')",
              selectedIdentifier, rx));
    }
  }

  /**
   * Selects a crosstool toolchain corresponding to the given crosstool configuration options. If
   * all of these options are null, it returns the default toolchain specified in the crosstool
   * release. If only cpu is non-null, it returns the default toolchain for that cpu, as specified
   * in the crosstool release. Otherwise, all values must be non-null, and this method returns the
   * toolchain which matches all of the values.
   *
   * @throws NullPointerException if {@code release} is null
   * @throws InvalidConfigurationException if no matching toolchain can be found, or if the input
   *     parameters do not obey the constraints described above
   */
  private static CToolchain selectToolchainUsingCpuAndMaybeCompiler(
      CrosstoolRelease release, CrosstoolConfigurationIdentifier config)
      throws InvalidConfigurationException {
    if (config.getCompiler() != null) {
      ArrayList<CToolchain> candidateToolchains = new ArrayList<>();
      for (CToolchain toolchain : release.getToolchainList()) {
        if (config.isCandidateToolchain(toolchain)) {
          candidateToolchains.add(toolchain);
        }
      }
      switch (candidateToolchains.size()) {
        case 0:
          {
            StringBuilder message = new StringBuilder();
            message.append("No toolchain found for");
            message.append(config.describeFlags());
            message.append(". Valid toolchains are: ");
            describeToolchainList(message, release.getToolchainList());
            throw new InvalidConfigurationException(message.toString());
          }
        case 1:
          return candidateToolchains.get(0);
        default:
          {
            StringBuilder message = new StringBuilder();
            message.append("Multiple toolchains found for");
            message.append(config.describeFlags());
            message.append(": ");
            describeToolchainList(message, candidateToolchains);
            throw new InvalidConfigurationException(message.toString());
          }
      }
    }
    String selectedIdentifier = null;
    for (CrosstoolConfig.DefaultCpuToolchain selector : release.getDefaultToolchainList()) {
      if (selector.getCpu().equals(config.getCpu())) {
        selectedIdentifier = selector.getToolchainIdentifier();
        break;
      }
    }

    if (selectedIdentifier == null) {
      HashSet<String> seenCpus = new HashSet<>();
      StringBuilder errorMessageBuilder = new StringBuilder();
      errorMessageBuilder
          .append("No toolchain found for cpu '")
          .append(config.getCpu())
          .append("'. Valid cpus from default_toolchain entries are: [\n");
      for (CrosstoolConfig.DefaultCpuToolchain selector : release.getDefaultToolchainList()) {
        if (seenCpus.add(selector.getCpu())) {
          errorMessageBuilder.append("  ").append(selector.getCpu()).append(",\n");
        }
      }
      errorMessageBuilder.append("]. Valid toolchains are: ");
      describeToolchainList(errorMessageBuilder, release.getToolchainList());
      throw new InvalidConfigurationException(errorMessageBuilder.toString());
    }
    checkToolchain(selectedIdentifier);

    for (CToolchain toolchain : release.getToolchainList()) {
      if (toolchain.getToolchainIdentifier().equals(selectedIdentifier)) {
        return toolchain;
      }
    }

    throw new InvalidConfigurationException(
        "Inconsistent crosstool configuration; no toolchain "
            + "corresponding to '"
            + selectedIdentifier
            + "' found for cpu '"
            + config.getCpu()
            + "'");
  }

  /**
   * Appends a series of toolchain descriptions (as the blaze command line flags that would specify
   * that toolchain) to 'message'.
   */
  private static void describeToolchainList(
      StringBuilder message, Collection<CToolchain> toolchains) {
    message.append("[\n");
    for (CrosstoolConfig.CToolchain toolchain : toolchains) {
      message.append("  ");
      message.append(toolchain.getToolchainIdentifier());
      message.append(": ");
      message.append(
          CrosstoolConfigurationIdentifier.fromToolchain(toolchain).describeFlags().trim());
      message.append(",\n");
    }
    message.append("]");
  }
}
