// 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 com.google.common.base.Preconditions;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ListMultimap;
import com.google.devtools.common.options.OptionPriority.PriorityCategory;
import com.google.devtools.common.options.OptionsParser.ConstructionException;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/**
 * The value of an option.
 *
 * <p>This takes care of tracking the final value as multiple instances of an option are parsed.
 */
public abstract class OptionValueDescription {

  protected final OptionDefinition optionDefinition;

  public OptionValueDescription(OptionDefinition optionDefinition) {
    this.optionDefinition = optionDefinition;
  }

  public OptionDefinition getOptionDefinition() {
    return optionDefinition;
  }

  /** Returns the current or final value of this option. */
  public abstract Object getValue();

  /** Returns the source(s) of this option, if there were multiple, duplicates are removed. */
  public abstract String getSourceString();

  /**
   * Add an instance of the option to this value. The various types of options are in charge of
   * making sure that the value is correctly stored, with proper tracking of its priority and
   * placement amongst other options.
   *
   * @return a bundle containing arguments that need to be parsed further.
   */
  abstract ExpansionBundle addOptionInstance(
      ParsedOptionDescription parsedOption, List<String> warnings) throws OptionsParsingException;

  /**
   * Grouping of convenience for the options that expand to other options, to attach an
   * option-appropriate source string along with the options that need to be parsed.
   */
  public static class ExpansionBundle {
    List<String> expansionArgs;
    String sourceOfExpansionArgs;

    public ExpansionBundle(List<String> args, String source) {
      expansionArgs = args;
      sourceOfExpansionArgs = source;
    }
  }

  /**
   * Returns the canonical instances of this option - the instances that affect the current value.
   *
   * <p>For options that do not have values in their own right, this should be the empty list. In
   * contrast, the DefaultOptionValue does not have a canonical form at all, since it was never set,
   * and is null.
   */
  @Nullable
  public abstract List<ParsedOptionDescription> getCanonicalInstances();

  /**
   * For the given option, returns the correct type of OptionValueDescription, to which unparsed
   * values can be added.
   *
   * <p>The categories of option types are non-overlapping, an invariant checked by the
   * OptionProcessor at compile time.
   */
  public static OptionValueDescription createOptionValueDescription(
      OptionDefinition option, OptionsData optionsData) {
    if (option.isExpansionOption()) {
      return new ExpansionOptionValueDescription(option, optionsData);
    } else if (option.allowsMultiple()) {
      return new RepeatableOptionValueDescription(option);
    } else if (option.hasImplicitRequirements()) {
      return new OptionWithImplicitRequirementsValueDescription(option);
    } else {
      return new SingleOptionValueDescription(option);
    }
  }

  /**
   * For options that have not been set, this will return a correct OptionValueDescription for the
   * default value.
   */
  public static OptionValueDescription getDefaultOptionValue(OptionDefinition option) {
    return new DefaultOptionValueDescription(option);
  }

  private static class DefaultOptionValueDescription extends OptionValueDescription {

    private DefaultOptionValueDescription(OptionDefinition optionDefinition) {
      super(optionDefinition);
    }

    @Override
    public Object getValue() {
      return optionDefinition.getDefaultValue();
    }

    @Override
    public String getSourceString() {
      return null;
    }

    @Override
    ExpansionBundle addOptionInstance(ParsedOptionDescription parsedOption, List<String> warnings) {
      throw new IllegalStateException(
          "Cannot add values to the default option value. Create a modifiable "
              + "OptionValueDescription using createOptionValueDescription() instead.");
    }

    @Override
    public ImmutableList<ParsedOptionDescription> getCanonicalInstances() {
      return null;
    }
  }

  /**
   * The form of a value for a default type of flag, one that does not accumulate multiple values
   * and has no expansion.
   */
  private static class SingleOptionValueDescription extends OptionValueDescription {
    private ParsedOptionDescription effectiveOptionInstance;
    private Object effectiveValue;

    private SingleOptionValueDescription(OptionDefinition optionDefinition) {
      super(optionDefinition);
      if (optionDefinition.allowsMultiple()) {
        throw new ConstructionException("Can't have a single value for an allowMultiple option.");
      }
      if (optionDefinition.isExpansionOption()) {
        throw new ConstructionException("Can't have a single value for an expansion option.");
      }
      effectiveOptionInstance = null;
      effectiveValue = null;
    }

    @Override
    public Object getValue() {
      return effectiveValue;
    }

    @Override
    public String getSourceString() {
      return effectiveOptionInstance.getSource();
    }

    // Warnings should not end with a '.' because the internal reporter adds one automatically.
    @Override
    ExpansionBundle addOptionInstance(ParsedOptionDescription parsedOption, List<String> warnings)
        throws OptionsParsingException {
      // This might be the first value, in that case, just store it!
      if (effectiveOptionInstance == null) {
        effectiveOptionInstance = parsedOption;
        effectiveValue = effectiveOptionInstance.getConvertedValue();
        return null;
      }

      // If there was another value, check whether the new one will override it, and if so,
      // log warnings describing the change.
      if (parsedOption.getPriority().compareTo(effectiveOptionInstance.getPriority()) >= 0) {
        // Identify the option that might have led to the current and new value of this option.
        ParsedOptionDescription implicitDependent = parsedOption.getImplicitDependent();
        ParsedOptionDescription expandedFrom = parsedOption.getExpandedFrom();
        ParsedOptionDescription optionThatDependsOnEffectiveValue =
            effectiveOptionInstance.getImplicitDependent();
        ParsedOptionDescription optionThatExpandedToEffectiveValue =
            effectiveOptionInstance.getExpandedFrom();

        Object newValue = parsedOption.getConvertedValue();
        // Output warnings if there is conflicting options set different values in a way that might
        // not have been obvious to the user, such as through expansions and implicit requirements.
        if (effectiveValue != null && !effectiveValue.equals(newValue)) {
          boolean samePriorityCategory =
              parsedOption
                  .getPriority()
                  .getPriorityCategory()
                  .equals(effectiveOptionInstance.getPriority().getPriorityCategory());
          if ((implicitDependent != null) && (optionThatDependsOnEffectiveValue != null)) {
            if (!implicitDependent.equals(optionThatDependsOnEffectiveValue)) {
              warnings.add(
                  String.format(
                      "%s is implicitly defined by both %s and %s",
                      optionDefinition, optionThatDependsOnEffectiveValue, implicitDependent));
            }
          } else if ((implicitDependent != null) && samePriorityCategory) {
            warnings.add(
                String.format(
                    "%s is implicitly defined by %s; the implicitly set value "
                        + "overrides the previous one",
                    optionDefinition, implicitDependent));
          } else if (optionThatDependsOnEffectiveValue != null) {
            warnings.add(
                String.format(
                    "A new value for %s overrides a previous implicit setting of that "
                        + "option by %s",
                    optionDefinition, optionThatDependsOnEffectiveValue));
          } else if (samePriorityCategory
              && parsedOption
                  .getPriority()
                  .getPriorityCategory()
                  .equals(PriorityCategory.COMMAND_LINE)
              && ((optionThatExpandedToEffectiveValue == null) && (expandedFrom != null))) {
            // Create a warning if an expansion option overrides an explicit option:
            warnings.add(
                String.format(
                    "%s was expanded and now overrides the explicit option %s with %s",
                    expandedFrom,
                    effectiveOptionInstance.getCommandLineForm(),
                    parsedOption.getCommandLineForm()));
          } else if ((optionThatExpandedToEffectiveValue != null) && (expandedFrom != null)) {
            warnings.add(
                String.format(
                    "%s was expanded to from both %s and %s",
                    optionDefinition, optionThatExpandedToEffectiveValue, expandedFrom));
          }
        }

        // Record the new value:
        effectiveOptionInstance = parsedOption;
        effectiveValue = newValue;
      }
      return null;
    }

    @Override
    public ImmutableList<ParsedOptionDescription> getCanonicalInstances() {
      // If the current option is an implicit requirement, we don't need to list this value since
      // the parent implies it. In this case, it is sufficient to not list this value at all.
      if (effectiveOptionInstance.getImplicitDependent() == null) {
        return ImmutableList.of(effectiveOptionInstance);
      }
      return ImmutableList.of();
    }
  }

  /** The form of a value for an option that accumulates multiple values on the command line. */
  private static class RepeatableOptionValueDescription extends OptionValueDescription {
    ListMultimap<OptionPriority, ParsedOptionDescription> parsedOptions;
    ListMultimap<OptionPriority, Object> optionValues;

    private RepeatableOptionValueDescription(OptionDefinition optionDefinition) {
      super(optionDefinition);
      if (!optionDefinition.allowsMultiple()) {
        throw new ConstructionException(
            "Can't have a repeated value for a non-allowMultiple option.");
      }
      parsedOptions = ArrayListMultimap.create();
      optionValues = ArrayListMultimap.create();
    }

    @Override
    public String getSourceString() {
      return parsedOptions
          .asMap()
          .entrySet()
          .stream()
          .sorted(Comparator.comparing(Map.Entry::getKey))
          .map(Map.Entry::getValue)
          .flatMap(Collection::stream)
          .map(ParsedOptionDescription::getSource)
          .distinct()
          .collect(Collectors.joining(", "));
    }

    @Override
    public ImmutableList<Object> getValue() {
      // Sort the results by option priority and return them in a new list. The generic type of
      // the list is not known at runtime, so we can't use it here.
      return optionValues.asMap().entrySet().stream()
          .sorted(Comparator.comparing(Map.Entry::getKey))
          .map(Map.Entry::getValue)
          .flatMap(Collection::stream)
          .collect(ImmutableList.toImmutableList());
    }

    @Override
    ExpansionBundle addOptionInstance(ParsedOptionDescription parsedOption, List<String> warnings)
        throws OptionsParsingException {
      // For repeatable options, we allow flags that take both single values and multiple values,
      // potentially collapsing them down.
      Object convertedValue = parsedOption.getConvertedValue();
      OptionPriority priority = parsedOption.getPriority();
      parsedOptions.put(priority, parsedOption);
      if (convertedValue instanceof List<?>) {
        optionValues.putAll(priority, (List<?>) convertedValue);
      } else {
        optionValues.put(priority, convertedValue);
      }
      return null;
    }

    @Override
    public ImmutableList<ParsedOptionDescription> getCanonicalInstances() {
      return parsedOptions
          .asMap()
          .entrySet()
          .stream()
          .sorted(Comparator.comparing(Map.Entry::getKey))
          .map(Map.Entry::getValue)
          .flatMap(Collection::stream)
          // Only provide the options that aren't implied elsewhere.
          .filter(optionDesc -> optionDesc.getImplicitDependent() == null)
          .collect(ImmutableList.toImmutableList());
    }
  }

  /**
   * The form of a value for an expansion option, one that does not have its own value but expands
   * in place to other options. This should be used for both flags with a static expansion defined
   * in {@link Option#expansion()} and flags with an {@link Option#expansionFunction()}.
   */
  private static class ExpansionOptionValueDescription extends OptionValueDescription {
    private final List<String> expansion;

    private ExpansionOptionValueDescription(
        OptionDefinition optionDefinition, OptionsData optionsData) {
      super(optionDefinition);
      this.expansion = optionsData.getEvaluatedExpansion(optionDefinition);
      if (!optionDefinition.isExpansionOption()) {
        throw new ConstructionException(
            "Options without expansions can't be tracked using ExpansionOptionValueDescription");
      }
    }

    @Override
    public Object getValue() {
      return null;
    }

    @Override
    public String getSourceString() {
      return null;
    }

    @Override
    ExpansionBundle addOptionInstance(ParsedOptionDescription parsedOption, List<String> warnings) {
      if (parsedOption.getUnconvertedValue() != null
          && !parsedOption.getUnconvertedValue().isEmpty()) {
        warnings.add(
            String.format(
                "%s is an expansion option. It does not accept values, and does not change its "
                    + "expansion based on the value provided. Value '%s' will be ignored.",
                optionDefinition, parsedOption.getUnconvertedValue()));
      }

      return new ExpansionBundle(
          expansion,
          (parsedOption.getSource() == null)
              ? String.format("expanded from %s", optionDefinition)
              : String.format(
                  "expanded from %s (source %s)", optionDefinition, parsedOption.getSource()));
    }

    @Override
    public ImmutableList<ParsedOptionDescription> getCanonicalInstances() {
      // The options this expands to are incorporated in their own right - this option does
      // not have a canonical form.
      return ImmutableList.of();
    }
  }

  /** The form of a value for a flag with implicit requirements. */
  private static class OptionWithImplicitRequirementsValueDescription
      extends SingleOptionValueDescription {

    private OptionWithImplicitRequirementsValueDescription(OptionDefinition optionDefinition) {
      super(optionDefinition);
      if (!optionDefinition.hasImplicitRequirements()) {
        throw new ConstructionException(
            "Options without implicit requirements can't be tracked using "
                + "OptionWithImplicitRequirementsValueDescription");
      }
    }

    @Override
    ExpansionBundle addOptionInstance(ParsedOptionDescription parsedOption, List<String> warnings)
        throws OptionsParsingException {
      // This is a valued flag, its value is handled the same way as a normal
      // SingleOptionValueDescription. (We check at compile time that these flags aren't
      // "allowMultiple")
      ExpansionBundle superExpansion = super.addOptionInstance(parsedOption, warnings);
      Preconditions.checkArgument(
          superExpansion == null, "SingleOptionValueDescription should not expand to anything.");
      if (parsedOption.getConvertedValue().equals(optionDefinition.getDefaultValue())) {
        warnings.add(
            String.format(
                "%s sets %s to its default value. Since this option has implicit requirements that "
                    + "are set whenever the option is explicitly provided, regardless of the "
                    + "value, this will behave differently than letting a default be a default. "
                    + "Specifically, this options expands to {%s}.",
                parsedOption.getCommandLineForm(),
                optionDefinition,
                String.join(" ", optionDefinition.getImplicitRequirements())));
      }

      // Now deal with the implicit requirements.
      return new ExpansionBundle(
          ImmutableList.copyOf(optionDefinition.getImplicitRequirements()),
          (parsedOption.getSource() == null)
              ? String.format("implicit requirement of %s", optionDefinition)
              : String.format(
                  "implicit requirement of %s (source %s)",
                  optionDefinition, parsedOption.getSource()));
    }
  }
}


