// 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.OptionsParser.ConstructionException;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
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.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
              && ((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(Entry::getKey))
          .map(Entry::getValue)
          .flatMap(Collection::stream)
          .map(ParsedOptionDescription::getSource)
          .distinct()
          .collect(Collectors.joining(", "));
    }

    @Override
    public List<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(Entry::getKey))
          .map(Entry::getValue)
          .flatMap(Collection::stream)
          .collect(Collectors.toList());
    }

    @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(Entry::getKey))
          .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()));
    }
  }
}


