// Copyright 2014 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 static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.io.BaseEncoding;
import com.google.devtools.build.lib.analysis.RedirectChaser;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigurationEnvironment;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.NoSuchThingException;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LipoMode;
import com.google.protobuf.TextFormat;
import com.google.protobuf.TextFormat.ParseException;
import com.google.protobuf.UninitializedMessageException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.ExecutionException;
import javax.annotation.Nullable;

/**
 * A loader that reads Crosstool configuration files and creates CToolchain
 * instances from them.
 *
 * <p>Note that this class contains a cache for the text format -> proto objects mapping of
 * Crosstool protos that is completely independent from Skyframe or anything else. This should be
 * done in a saner way.
 */
public class CrosstoolConfigurationLoader {
  private static final String CROSSTOOL_CONFIGURATION_FILENAME = "CROSSTOOL";

  /**
   * Cache for storing result of toReleaseConfiguration function based on path and md5 sum of
   * input file. We can use md5 because result of this function depends only on the file content.
   */
  private static final Cache<String, CrosstoolRelease> crosstoolReleaseCache =
      CacheBuilder.newBuilder().concurrencyLevel(4).maximumSize(100).build();
  /** A class that holds the results of reading a CROSSTOOL file. */
  @AutoCodec
  public static class CrosstoolFile {
    private final String location;
    private final CrosstoolConfig.CrosstoolRelease proto;
    private final String md5;

    @AutoCodec.Instantiator
    CrosstoolFile(String location, CrosstoolConfig.CrosstoolRelease proto, String md5) {
      this.location = location;
      this.proto = proto;
      this.md5 = md5;
    }

    /**
     * Returns a user-friendly location of the CROSSTOOL proto for error messages.
     */
    public String getLocation() {
      return location;
    }

    /**
     * Returns the parsed contents of the CROSSTOOL file.
     */
    public CrosstoolConfig.CrosstoolRelease getProto() {
      return proto;
    }

    /**
     * Returns an MD5 hash of the CROSSTOOL file contents.
     */
    public String getMd5() {
      return md5;
    }
  }

  private CrosstoolConfigurationLoader() {
  }

  /**
   * Reads the given <code>data</code> String, which must be in ascii format,
   * into a protocol buffer. It uses the <code>name</code> parameter for error
   * messages.
   *
   * @throws IOException if the parsing failed
   */
  @VisibleForTesting
  static CrosstoolConfig.CrosstoolRelease toReleaseConfiguration(String name, String data)
      throws IOException {
    CrosstoolConfig.CrosstoolRelease.Builder builder =
        CrosstoolConfig.CrosstoolRelease.newBuilder();
    try {
      TextFormat.merge(data, builder);
      return builder.build();
    } catch (ParseException e) {
      throw new IOException("Could not read the crosstool configuration file '" + name + "', "
          + "because of a parser error (" + e.getMessage() + ")");
    } catch (UninitializedMessageException e) {
      throw new IOException("Could not read the crosstool configuration file '" + name + "', "
          + "because of an incomplete protocol buffer (" + e.getMessage() + ")");
    }
  }

  /**
   * This class is the in-memory representation of a text-formatted Crosstool proto file.
   *
   * <p>This layer of abstraction is here so that we can load these protos either from BUILD files
   * or from CROSSTOOL files.
   *
   * <p>An implementation of this class should override {@link #getContents()} and call
   * the constructor with the MD5 checksum of what that method will return and a human-readable name
   * used in error messages.
   */
  private abstract static class CrosstoolProto {
    private final byte[] md5;
    private final String name;

    private CrosstoolProto(byte[] md5, String name) {
      this.md5 = md5;
      this.name = name;
    }

    /**
     * The binary MD5 checksum of the proto.
     */
    public byte[] getMd5() {
      return md5;
    }

    /**
     * A user-friendly string describing the location of the proto.
     */
    public String getName() {
      return name;
    }

    /**
     * The proto itself.
     */
    public abstract String getContents() throws IOException;
  }

  private static CrosstoolProto getCrosstoolProtofromBuildFile(
      ConfigurationEnvironment env, Label crosstoolTop) throws InterruptedException {
    Target target;
    try {
      target = env.getTarget(crosstoolTop);
    } catch (NoSuchThingException e) {
      throw new IllegalStateException(e);  // Should have beeen evaluated by RedirectChaser
    }

    if (!(target instanceof Rule)) {
      return null;
    }

    Rule rule = (Rule) target;
    if (!(rule.getRuleClass().equals("cc_toolchain_suite"))
        || !rule.isAttributeValueExplicitlySpecified("proto")) {
      return null;
    }

    final String contents = NonconfigurableAttributeMapper.of(rule).get("proto", Type.STRING);
    byte[] md5 = new Fingerprint().addBytes(contents.getBytes(UTF_8)).digestAndReset();
    return new CrosstoolProto(md5, "cc_toolchain_suite rule " + crosstoolTop.toString()) {

      @Override
      public String getContents() throws IOException {
        return contents;
      }
    };
  }

  private static CrosstoolProto getCrosstoolProtoFromCrosstoolFile(
      ConfigurationEnvironment env, Label crosstoolTop)
      throws IOException, InvalidConfigurationException, InterruptedException {
    final Path path;
    try {
      Package containingPackage = env.getTarget(crosstoolTop).getPackage();
      if (containingPackage == null) {
        return null;
      }
      path = env.getPath(containingPackage, CROSSTOOL_CONFIGURATION_FILENAME);
    } catch (NoSuchThingException e) {
      // Handled later
      return null;
    }

    if (path == null || !path.exists()) {
      return null;
    }

    return new CrosstoolProto(path.getDigest(), "CROSSTOOL file " + path.getPathString()) {
      @Override
      public String getContents() throws IOException {
        try (InputStream inputStream = path.getInputStream()) {
          return new String(FileSystemUtils.readContentAsLatin1(inputStream));
        }
      }
    };
  }

  private static CrosstoolFile findCrosstoolConfiguration(
      ConfigurationEnvironment env, Label crosstoolTop)
      throws IOException, InvalidConfigurationException, InterruptedException {

    CrosstoolProto crosstoolProto = getCrosstoolProtofromBuildFile(env, crosstoolTop);
    if (crosstoolProto == null) {
      crosstoolProto = getCrosstoolProtoFromCrosstoolFile(env, crosstoolTop);
    }

    if (crosstoolProto == null) {
      throw new InvalidConfigurationException("The crosstool_top you specified was resolved to '" +
          crosstoolTop + "', which does not contain a CROSSTOOL file. " +
          "You can use a crosstool from the depot by specifying its label.");
    } else {
      // Do this before we read the data, so if it changes, we get a different MD5 the next time.
      // Alternatively, we could calculate the MD5 of the contents, which we also read, but this
      // is faster if the file comes from a file system with md5 support.
      final CrosstoolProto finalProto = crosstoolProto;
      String md5 = BaseEncoding.base16().lowerCase().encode(finalProto.getMd5());
      CrosstoolConfig.CrosstoolRelease release;
      try {
        release =
            crosstoolReleaseCache.get(
                md5, () -> toReleaseConfiguration(finalProto.getName(), finalProto.getContents()));
      } catch (ExecutionException e) {
        throw new InvalidConfigurationException(e);
      }

      return new CrosstoolFile(finalProto.getName(), release, md5);
    }
  }

  /** Reads a crosstool file. */
  @Nullable
  public static CrosstoolConfigurationLoader.CrosstoolFile readCrosstool(
      ConfigurationEnvironment env, Label crosstoolTop)
      throws InvalidConfigurationException, InterruptedException {
    crosstoolTop = RedirectChaser.followRedirects(env, crosstoolTop, "crosstool_top");
    if (crosstoolTop == null) {
      return null;
    }
    try {
      return findCrosstoolConfiguration(env, crosstoolTop);
    } catch (IOException e) {
      throw new InvalidConfigurationException(e);
    }
  }

  /**
   * 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
   */
  public static CrosstoolConfig.CToolchain selectToolchain(
      CrosstoolConfig.CrosstoolRelease release,
      BuildOptions options,
      Function<String, String> cpuTransformer)
      throws InvalidConfigurationException {
    CrosstoolConfigurationIdentifier config =
        CrosstoolConfigurationIdentifier.fromOptions(options);
    CppOptions cppOptions = options.get(CppOptions.class);
    return selectToolchain(
        release, config, cppOptions.getLipoMode(), cppOptions.convertLipoToThinLto, cpuTransformer);
  }

  /**
   * 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
   */
  public static CrosstoolConfig.CToolchain selectToolchain(
      CrosstoolConfig.CrosstoolRelease release,
      CrosstoolConfigurationIdentifier config,
      LipoMode lipoMode,
      boolean convertLipoToThinLto,
      Function<String, String> cpuTransformer)
      throws InvalidConfigurationException {
    if ((config.getCompiler() != null) || (config.getLibc() != null)) {
      ArrayList<CrosstoolConfig.CToolchain> candidateToolchains = new ArrayList<>();
      for (CrosstoolConfig.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;
    // We use fake CPU values to allow cross-platform builds for other languages that use the
    // C++ toolchain. Translate to the actual target architecture.
    String desiredCpu = cpuTransformer.apply(config.getCpu());
    boolean needsLipo = lipoMode != LipoMode.OFF && !convertLipoToThinLto;
    for (CrosstoolConfig.DefaultCpuToolchain selector : release.getDefaultToolchainList()) {
      if (needsLipo && !selector.getSupportsLipo()) {
        continue;
      }
      if (selector.getCpu().equals(desiredCpu)) {
        selectedIdentifier = selector.getToolchainIdentifier();
        break;
      }
    }

    if (selectedIdentifier == null) {
      HashSet<String> seenCpus = new HashSet<>();
      StringBuilder cpuBuilder = new StringBuilder();
      for (CrosstoolConfig.DefaultCpuToolchain selector : release.getDefaultToolchainList()) {
        if (seenCpus.add(selector.getCpu())) {
          cpuBuilder.append("  ").append(selector.getCpu()).append(",\n");
        }
      }
      throw new InvalidConfigurationException(
          "No default_toolchain found for cpu '"
              + desiredCpu
              + "'. Valid cpus are: [\n"
              + cpuBuilder
              + "]");
    }
    checkToolChain(selectedIdentifier, desiredCpu);

    for (CrosstoolConfig.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<CrosstoolConfig.CToolchain> toolchains) {
    message.append("[\n");
    for (CrosstoolConfig.CToolchain toolchain : toolchains) {
      message.append("  ");
      message.append(
          CrosstoolConfigurationIdentifier.fromToolchain(toolchain).describeFlags().trim());
      message.append(",\n");
    }
    message.append("]");
  }

  /**
   * 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, String cpu)
      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' for cpu '%s' is illegal (does not match '%s')",
          selectedIdentifier, cpu, rx));
    }
  }

  public static CrosstoolConfig.CrosstoolRelease getCrosstoolReleaseProto(
      ConfigurationEnvironment env,
      BuildOptions options,
      Label crosstoolTop,
      Function<String, String> cpuTransformer)
      throws InvalidConfigurationException, InterruptedException {
    CrosstoolConfigurationLoader.CrosstoolFile file =
        readCrosstool(env, crosstoolTop);
    // Make sure that we have the requested toolchain in the result. Throw an exception if not.
    selectToolchain(file.getProto(), options, cpuTransformer);
    return file.getProto();
  }
}
