// 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.common.options;

import static java.util.Comparator.comparing;

import com.google.common.collect.ImmutableList;
import com.google.devtools.common.options.OptionsParser.ConstructionException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * Everything the {@link OptionsParser} needs to know about how an option is defined.
 *
 * <p>An {@code OptionDefinition} is effectively a wrapper around the {@link Option} annotation and
 * the {@link Field} that is annotated, and should contain all logic about default settings and
 * behavior.
 */
public class OptionDefinition implements Comparable<OptionDefinition> {

  /**
   * A special value used to specify an absence of default value.
   *
   * @see Option#defaultValue
   */
  public static final String SPECIAL_NULL_DEFAULT_VALUE = "null";

  // TODO(b/65049598) make ConstructionException checked, which will make this checked as well.
  static class NotAnOptionException extends ConstructionException {
    NotAnOptionException(Field field) {
      super(
          "The field "
              + field.getName()
              + " does not have the right annotation to be considered an option.");
    }
  }

  /**
   * If the {@code field} is annotated with the appropriate @{@link Option} annotation, returns the
   * {@code OptionDefinition} for that option. Otherwise, throws a {@link NotAnOptionException}.
   *
   * <p>These values are cached in the {@link OptionsData} layer and should be accessed through
   * {@link OptionsParser#getOptionDefinitions(Class)}.
   */
  static OptionDefinition extractOptionDefinition(Field field) {
    Option annotation = field == null ? null : field.getAnnotation(Option.class);
    if (annotation == null) {
      throw new NotAnOptionException(field);
    }
    return new OptionDefinition(field, annotation);
  }

  private final Field field;
  private final Option optionAnnotation;
  private Converter<?> converter = null;
  private Object defaultValue = null;

  private OptionDefinition(Field field, Option optionAnnotation) {
    this.field = field;
    this.optionAnnotation = optionAnnotation;
  }

  /** Returns the underlying {@code field} for this {@code OptionDefinition}. */
  public Field getField() {
    return field;
  }

  /**
   * Returns the name of the option ("--name").
   *
   * <p>Labelled "Option" name to distinguish it from the field's name.
   */
  public String getOptionName() {
    return optionAnnotation.name();
  }

  /** The single-character abbreviation of the option ("-a"). */
  public char getAbbreviation() {
    return optionAnnotation.abbrev();
  }

  /** {@link Option#help()} */
  public String getHelpText() {
    return optionAnnotation.help();
  }

  /** {@link Option#valueHelp()} */
  public String getValueTypeHelpText() {
    return optionAnnotation.valueHelp();
  }

  /** {@link Option#defaultValue()} */
  public String getUnparsedDefaultValue() {
    return optionAnnotation.defaultValue();
  }

  /** {@link Option#category()} */
  public String getOptionCategory() {
    return optionAnnotation.category();
  }

  /** {@link Option#documentationCategory()} */
  public OptionDocumentationCategory getDocumentationCategory() {
    return optionAnnotation.documentationCategory();
  }

  /** {@link Option#effectTags()} */
  public OptionEffectTag[] getOptionEffectTags() {
    return optionAnnotation.effectTags();
  }

  /** {@link Option#metadataTags()} */
  public OptionMetadataTag[] getOptionMetadataTags() {
    return optionAnnotation.metadataTags();
  }

  /** {@link Option#converter()} ()} */
  @SuppressWarnings({"rawtypes"})
  public Class<? extends Converter> getProvidedConverter() {
    return optionAnnotation.converter();
  }

  /** {@link Option#allowMultiple()} */
  public boolean allowsMultiple() {
    return optionAnnotation.allowMultiple();
  }

  /** {@link Option#expansion()} */
  public String[] getOptionExpansion() {
    return optionAnnotation.expansion();
  }

  /** {@link Option#implicitRequirements()} ()} */
  public String[] getImplicitRequirements() {
    return optionAnnotation.implicitRequirements();
  }

  /** {@link Option#deprecationWarning()} ()} */
  public String getDeprecationWarning() {
    return optionAnnotation.deprecationWarning();
  }

  /** {@link Option#oldName()} ()} ()} */
  public String getOldOptionName() {
    return optionAnnotation.oldName();
  }

  /** Returns whether an option --foo has a negative equivalent --nofoo. */
  public boolean hasNegativeOption() {
    return getType().equals(boolean.class) || getType().equals(TriState.class);
  }

  /** The type of the optionDefinition. */
  public Class<?> getType() {
    return field.getType();
  }

  /** Whether this field has type Void. */
  boolean isVoidField() {
    return getType().equals(Void.class);
  }

  public boolean isSpecialNullDefault() {
    return SPECIAL_NULL_DEFAULT_VALUE.equals(getUnparsedDefaultValue()) && !getType().isPrimitive();
  }

  /** Returns whether the arg is an expansion option. */
  public boolean isExpansionOption() {
    return getOptionExpansion().length > 0;
  }

  /** Returns whether the arg is an expansion option. */
  public boolean hasImplicitRequirements() {
    return (getImplicitRequirements().length > 0);
  }

  /**
   * For an option that does not use {@link Option#allowMultiple}, returns its type. For an option
   * that does use it, asserts that the type is a {@code List<T>} and returns its element type
   * {@code T}.
   */
  Type getFieldSingularType() {
    Type fieldType = getField().getGenericType();
    if (allowsMultiple()) {
      // The validity of the converter is checked at compile time. We know the type to be
      // List<singularType>.
      ParameterizedType pfieldType = (ParameterizedType) fieldType;
      fieldType = pfieldType.getActualTypeArguments()[0];
    }
    return fieldType;
  }

  /**
   * Retrieves the {@link Converter} that will be used for this option, taking into account the
   * default converters if an explicit one is not specified.
   *
   * <p>Memoizes the converter-finding logic to avoid repeating the computation.
   */
  public Converter<?> getConverter() {
    if (converter != null) {
      return converter;
    }
    Class<? extends Converter> converterClass = getProvidedConverter();
    if (converterClass == Converter.class) {
      // No converter provided, use the default one.
      Type type = getFieldSingularType();
      converter = Converters.DEFAULT_CONVERTERS.get(type);
    } else {
      try {
        // Instantiate the given Converter class.
        Constructor<?> constructor = converterClass.getConstructor();
        converter = (Converter<?>) constructor.newInstance();
      } catch (SecurityException | IllegalArgumentException | ReflectiveOperationException e) {
        // This indicates an error in the Converter, and should be discovered the first time it is
        // used.
        throw new ConstructionException(
            String.format("Error in the provided converter for option %s", getField().getName()),
            e);
      }
    }
    return converter;
  }

  /**
   * Returns whether a field should be considered as boolean.
   *
   * <p>Can be used for usage help and controlling whether the "no" prefix is allowed.
   */
  public boolean usesBooleanValueSyntax() {
    return getType().equals(boolean.class)
        || getType().equals(TriState.class)
        || getConverter() instanceof BoolOrEnumConverter;
  }

  /** Returns the evaluated default value for this option & memoizes the result. */
  public Object getDefaultValue() {
    if (defaultValue != null) {
      return defaultValue;
    }

    if (isSpecialNullDefault()) {
      return allowsMultiple() ? ImmutableList.of() : null;
    }

    Converter<?> converter = getConverter();
    String defaultValueAsString = getUnparsedDefaultValue();
    try {
      Object convertedDefaultValue = converter.convert(defaultValueAsString);
      defaultValue =
          allowsMultiple()
              ? maybeWrapMultipleDefaultValue(convertedDefaultValue)
              : convertedDefaultValue;
    } catch (OptionsParsingException e) {
      throw new ConstructionException(
          String.format(
              "OptionsParsingException while retrieving the default value for %s: %s",
              getField().getName(), e.getMessage()),
          e);
    }

    return defaultValue;
  }

  /**
   * Wraps a converted default value into a {@link List} if the converter doesn't do it on its own.
   *
   * <p>This is to make sure multiple ({@link Option#allowMultiple()}) options' default values are
   * always converted to a list representation.
   *
   * <p>In general it mimics the {@link RepeatableOptionValueDescription# addOptionInstance}
   * behavior: multiple option default value is treated as if it appeared on the command line only
   * once with the specified value.
   *
   * <p>Note that on a command line multiple options can appear multiple times while each can
   * support multiple values (e.g. comma-separated - depending on a converter). Thus default value
   * for multiple option is (depending on the converter) a strict subset of the set of potential
   * values for the option.
   */
  @SuppressWarnings("unchecked") // Not an unchecked cast - there's an explicit type check before it
  private static List<Object> maybeWrapMultipleDefaultValue(Object convertedDefaultValue) {
    if (convertedDefaultValue instanceof List) {
      return (List<Object>) convertedDefaultValue;
    } else {
      return Arrays.asList(convertedDefaultValue);
    }
  }

  /**
   * {@link OptionDefinition} is really a wrapper around a {@link Field} that caches information
   * obtained through reflection. Checking that the fields they represent are equal is sufficient to
   * check that two {@link OptionDefinition} objects are equal.
   */
  @Override
  public boolean equals(Object object) {
    if (!(object instanceof OptionDefinition)) {
      return false;
    }
    OptionDefinition otherOption = (OptionDefinition) object;
    return field.equals(otherOption.field);
  }

  @Override
  public int hashCode() {
    return field.hashCode();
  }

  @Override
  public int compareTo(OptionDefinition o) {
    return getOptionName().compareTo(o.getOptionName());
  }

  @Override
  public String toString() {
    return String.format("option '--%s'", getOptionName());
  }

  static final Comparator<OptionDefinition> BY_OPTION_NAME =
      Comparator.comparing(OptionDefinition::getOptionName);

  /**
   * An ordering relation for option-field fields that first groups together options of the same
   * category, then sorts by name within the category.
   */
  static final Comparator<OptionDefinition> BY_CATEGORY =
      comparing(OptionDefinition::getOptionCategory).thenComparing(BY_OPTION_NAME);
}
