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

import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.LocationExpander.Options;
import com.google.devtools.build.lib.analysis.stringtemplate.ExpansionException;
import com.google.devtools.build.lib.analysis.stringtemplate.TemplateContext;
import com.google.devtools.build.lib.cmdline.Label;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import javax.annotation.Nullable;

/**
 * Expands $(location) and $(locations) tags inside target attributes. You can specify something
 * like this in the BUILD file:
 *
 * <pre>
 * somerule(name='some name',
 *          someopt = [ '$(location //mypackage:myhelper)' ],
 *          ...)
 * </pre>
 *
 * and location will be substituted with //mypackage:myhelper executable output.
 *
 * <p>Note that this expander will always expand labels in srcs, deps, and tools attributes, with
 * data being optional.
 *
 * <p>DO NOT USE DIRECTLY! Use RuleContext.getExpander() instead.
 */
final class LocationTemplateContext implements TemplateContext {
  private final TemplateContext delegate;
  private final ImmutableMap<String, Function<String, String>> functions;

  private LocationTemplateContext(
      TemplateContext delegate,
      Label root,
      Supplier<Map<Label, Collection<Artifact>>> locationMap,
      boolean execPaths) {
    this.delegate = delegate;
    this.functions = LocationExpander.allLocationFunctions(root, locationMap, execPaths);
  }

  private LocationTemplateContext(
      TemplateContext delegate,
      RuleContext ruleContext,
      @Nullable ImmutableMap<Label, ImmutableCollection<Artifact>> labelMap,
      ImmutableSet<Options> options) {
    this(
        delegate,
        ruleContext.getLabel(),
        // Use a memoizing supplier to avoid eagerly building the location map.
        Suppliers.memoize(
            () -> LocationExpander.buildLocationMap(
                ruleContext, labelMap, options.contains(Options.ALLOW_DATA))),
        options.contains(Options.EXEC_PATHS));
  }

  public LocationTemplateContext(
      TemplateContext delegate,
      RuleContext ruleContext,
      @Nullable ImmutableMap<Label, ImmutableCollection<Artifact>> labelMap,
      LocationExpander.Options... options) {
    this(delegate, ruleContext, labelMap, ImmutableSet.copyOf(options));
  }

  public LocationTemplateContext(
      TemplateContext delegate, RuleContext ruleContext, LocationExpander.Options... options) {
    this(delegate, ruleContext, null, ImmutableSet.copyOf(options));
  }

  @Override
  public String lookupVariable(String name) throws ExpansionException {
    return delegate.lookupVariable(name);
  }

  @Override
  public String lookupFunction(String name, String param) throws ExpansionException {
    try {
      Function<String, String> f = functions.get(name);
      if (f != null) {
        return f.apply(param);
      }
    } catch (IllegalStateException e) {
      throw new ExpansionException(e.getMessage(), e);
    }
    return delegate.lookupFunction(name, param);
  }
}
