// 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.

package com.google.devtools.build.lib.runtime;

import com.google.common.collect.ImmutableList;
import com.google.devtools.common.options.Converter;
import com.google.devtools.common.options.ExpansionFunction;
import com.google.devtools.common.options.IsolatedOptionsData;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDefinition;
import com.google.devtools.common.options.OptionMetadataTag;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
import java.util.ArrayList;
import java.util.Map;

/**
 * Expansion function for {@code --all_incompatible_changes}. Expands to all options of form {@code
 * --incompatible_*} that are declared in the {@link OptionsBase} subclasses that are passed to the
 * parser.
 *
 * <p>The incompatible changes system provides users with a uniform way of opting into backwards-
 * incompatible changes, in order to test whether their builds will be broken by an upcoming
 * release. When adding a new breaking change to Bazel, prefer to use this mechanism for guarding
 * the behavior.
 *
 * <p>An {@link Option}-annotated field that is considered an incompatible change must satisfy the
 * following requirements.
 *
 * <ul>
 *   <li>the {@link Option#name} must be prefixed with "incompatible_"
 *   <li>the {@link Option#metadataTags()} must include {@link
 *       OptionMetadataTag#INCOMPATIBLE_CHANGE} and {@link
 *       OptionMetadataTag#TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES}
 *   <li>the {@link Option#help} field must be set, and must refer the user to information about
 *       what the change does and how to migrate their code
 *   <li>the following fields may not be used: {@link Option#abbrev}, {@link Option#valueHelp},
 *       {@link Option#converter}, {@link Option#allowMultiple}, and {@link Option#oldName}
 * </ul>
 *
 * Example:
 *
 * <pre>{@code
 * @Option(
 *   name = "incompatible_foo",
 *   metadataTags = {
 *     OptionMetadataTag.INCOMPATIBLE_CHANGE,
 *     OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES
 *   },
 *   defaultValue = "false",
 *   help = "Deprecates bar and changes the semantics of baz. To migrate your code see [...].")
 * public boolean incompatibleFoo;
 * }</pre>
 *
 * All options that have either the "incompatible_" prefix or the tag {@link
 * OptionMetadataTag#TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES} will be validated using the above
 * criteria. Any failure will cause {@link IllegalArgumentException} to be thrown, which will cause
 * the construction of the {@link OptionsParser} to fail with the <i>unchecked</i> exception {@link
 * OptionsParser.ConstructionException}. Therefore, when adding a new incompatible change, be aware
 * that an error in the specification of the {@code @Option} will exercise failure code paths in the
 * early part of the Bazel server execution.
 *
 * <p>After the breaking change has been enabled by default, it is recommended (required?) that the
 * flag stick around for a few releases, to provide users the flexibility to opt out. Even after
 * enabling the behavior unconditionally, it can still be useful to keep the flag around as a valid
 * no-op so that Bazel invocations are not immediately broken.
 *
 * <p>Generally speaking, we should never reuse names for multiple options. Therefore, when choosing
 * a name for a new incompatible change, try to describe not just the affected feature, but what the
 * change to that feature is. This avoids conflicts in case the feature changes multiple times. For
 * example, {@code "--incompatible_depset_constructor"} is ambiguous because it only communicates
 * that there is a change to how depsets are constructed, but {@code
 * "--incompatible_disallow_set_constructor"} uniquely says that the {@code set} alias for the
 * depset constructor is being disallowed.
 */
// Javadoc can't resolve inner classes.
@SuppressWarnings("javadoc")
public class AllIncompatibleChangesExpansion implements ExpansionFunction {

  // The reserved prefix for all incompatible change option names.
  public static final String INCOMPATIBLE_NAME_PREFIX = "incompatible_";

  /**
   * Ensures that the given option satisfies all the requirements on incompatible change options
   * enumerated above.
   *
   * <p>If any of these requirements are not satisfied, {@link IllegalArgumentException} is thrown,
   * as this constitutes an internal error in the declaration of the option.
   */
  private static void validateIncompatibleChange(OptionDefinition optionDefinition) {
    String prefix = String.format("Incompatible change %s ", optionDefinition);

    // To avoid ambiguity, and the suggestion of using .isEmpty().
    String defaultString = "";

    // Validate that disallowed fields aren't used. These will need updating if the default values
    // in Option ever change, and perhaps if new fields are added.
    if (optionDefinition.getAbbreviation() != '\0') {
      throw new IllegalArgumentException(prefix + "must not use the abbrev field");
    }
    if (!optionDefinition.getValueTypeHelpText().equals(defaultString)) {
      throw new IllegalArgumentException(prefix + "must not use the valueHelp field");
    }
    if (optionDefinition.getProvidedConverter() != Converter.class) {
      throw new IllegalArgumentException(prefix + "must not use the converter field");
    }
    if (optionDefinition.allowsMultiple()) {
      throw new IllegalArgumentException(prefix + "must not use the allowMultiple field");
    }
    if (optionDefinition.hasImplicitRequirements()) {
      throw new IllegalArgumentException(prefix + "must not use the implicitRequirements field");
    }
    if (!optionDefinition.getOldOptionName().equals(defaultString)) {
      throw new IllegalArgumentException(prefix + "must not use the oldName field");
    }

    // Validate the fields that are actually allowed.
    if (!optionDefinition.getOptionName().startsWith(INCOMPATIBLE_NAME_PREFIX)) {
      throw new IllegalArgumentException(prefix + "must have name starting with \"incompatible_\"");
    }
    if (!ImmutableList.copyOf(optionDefinition.getOptionMetadataTags())
        .contains(OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES)) {
      throw new IllegalArgumentException(
          prefix
              + "must have metadata tag OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES");
    }
    if (!ImmutableList.copyOf(optionDefinition.getOptionMetadataTags())
        .contains(OptionMetadataTag.INCOMPATIBLE_CHANGE)) {
      throw new IllegalArgumentException(
          prefix + "must have metadata tag OptionMetadataTag.INCOMPATIBLE_CHANGE");
    }
    if (!optionDefinition.isExpansionOption()) {
      if (!optionDefinition.getType().equals(Boolean.TYPE)) {
        throw new IllegalArgumentException(
            prefix + "must have boolean type (unless it's an expansion option)");
      }
    }
    if (optionDefinition.getHelpText().equals(defaultString)) {
      throw new IllegalArgumentException(
          prefix
              + "must have a \"help\" string that refers the user to "
              + "information about this change and how to migrate their code");
    }
  }

  @Override
  public ImmutableList<String> getExpansion(IsolatedOptionsData optionsData) {
    // Grab all registered options that are identified as incompatible changes by either name or
    // by OptionMetadataTag. Ensure they satisfy our requirements.
    ArrayList<String> incompatibleChanges = new ArrayList<>();
    for (Map.Entry<String, OptionDefinition> entry : optionsData.getAllOptionDefinitions()) {
      OptionDefinition optionDefinition = entry.getValue();
      if (optionDefinition.getOptionName().startsWith(INCOMPATIBLE_NAME_PREFIX)
          || ImmutableList.copyOf(optionDefinition.getOptionMetadataTags())
              .contains(OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES)) {
        validateIncompatibleChange(optionDefinition);
        incompatibleChanges.add("--" + optionDefinition.getOptionName());
      }
    }
    // Sort to get a deterministic canonical order. This probably isn't necessary because the
    // options parser will do its own sorting when canonicalizing, but it seems like it can't hurt.
    incompatibleChanges.sort(null);
    return ImmutableList.copyOf(incompatibleChanges);
  }
}
