// 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 static java.util.stream.Collectors.joining;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.analysis.platform.PlatformProviderUtils;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
import com.google.devtools.build.lib.syntax.SkylarkIndexable;
import com.google.devtools.build.lib.util.OrderedSetMultimap;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;

/** Contains toolchain-related information needed for a {@link RuleContext}. */
@Immutable
@ThreadSafe
@SkylarkModule(
  name = "ToolchainContext",
  category = SkylarkModuleCategory.BUILTIN,
  doc = "Stores toolchains available to a given rule."
)
public class ToolchainContext {
  public static ToolchainContext create(
      String targetDescription,
      PlatformInfo executionPlatform,
      PlatformInfo targetPlatform,
      Set<Label> requiredToolchains,
      ImmutableBiMap<Label, Label> resolvedLabels) {
    return new ToolchainContext(
        targetDescription,
        executionPlatform,
        targetPlatform,
        requiredToolchains,
        new ResolvedToolchainLabels(resolvedLabels));
  }

  /** The {@link PlatformInfo} describing where these toolchains can be executed. */
  private final PlatformInfo executionPlatform;

  /** The {@link PlatformInfo} describing the outputs of these toolchains. */
  private final PlatformInfo targetPlatform;

  /** Description of the target the toolchain context applies to, for use in error messages. */
  private final String targetDescription;

  /** The toolchain types that are required by the target. */
  private final ImmutableList<Label> requiredToolchains;

  /** Map from toolchain type labels to actual resolved toolchain labels. */
  private final ResolvedToolchainLabels resolvedToolchainLabels;

  /** Stores the actual ToolchainInfo provider for each toolchain type. */
  private ResolvedToolchainProviders resolvedToolchainProviders;

  private ToolchainContext(
      String targetDescription,
      PlatformInfo executionPlatform,
      PlatformInfo targetPlatform,
      Set<Label> requiredToolchains,
      ResolvedToolchainLabels resolvedToolchainLabels) {
    this.targetDescription = targetDescription;
    this.executionPlatform = executionPlatform;
    this.targetPlatform = targetPlatform;
    this.requiredToolchains = ImmutableList.copyOf(requiredToolchains);
    this.resolvedToolchainLabels = resolvedToolchainLabels;
    this.resolvedToolchainProviders =
        new ResolvedToolchainProviders(ImmutableMap.<Label, ToolchainInfo>of());
  }

  public PlatformInfo getExecutionPlatform() {
    return executionPlatform;
  }

  public PlatformInfo getTargetPlatform() {
    return targetPlatform;
  }

  public ImmutableList<Label> getRequiredToolchains() {
    return requiredToolchains;
  }

  public void resolveToolchains(
      OrderedSetMultimap<Attribute, ConfiguredTargetAndData> prerequisiteMap) {
    if (!this.requiredToolchains.isEmpty()) {
      this.resolvedToolchainProviders =
          new ResolvedToolchainProviders(findToolchains(resolvedToolchainLabels, prerequisiteMap));
    }
  }

  @Nullable
  public SkylarkIndexable getResolvedToolchainProviders() {
    return resolvedToolchainProviders;
  }

  public ImmutableSet<Label> getResolvedToolchainLabels() {
    return resolvedToolchainLabels.getToolchainLabels();
  }

  /** Returns the {@link Label}s from the {@link NestedSet} that refer to toolchain dependencies. */
  public Set<Label> filterToolchainLabels(Set<Label> labels) {
    return labels
        .stream()
        .filter(label -> resolvedToolchainLabels.isToolchainDependency(label))
        .collect(ImmutableSet.toImmutableSet());
  }

  /** Tracks the mapping from toolchain type label to the label of the actual resolved toolchain. */
  private static class ResolvedToolchainLabels {
    private final ImmutableBiMap<Label, Label> toolchainLabels;

    private ResolvedToolchainLabels(ImmutableBiMap<Label, Label> toolchainLabels) {
      this.toolchainLabels = toolchainLabels;
    }

    public Label getType(Label toolchainLabel) {
      return toolchainLabels.inverse().get(toolchainLabel);
    }

    public Label getResolvedToolchainLabel(Label toolchainType) {
      return toolchainLabels.get(toolchainType);
    }

    public ImmutableSet<Label> getToolchainLabels() {
      return toolchainLabels.values();
    }

    public boolean isToolchainDependency(Label label) {
      return toolchainLabels.containsValue(label);
    }
  }

  private static ImmutableMap<Label, ToolchainInfo> findToolchains(
      ResolvedToolchainLabels resolvedToolchainLabels,
      OrderedSetMultimap<Attribute, ConfiguredTargetAndData> prerequisiteMap) {
    // Find the prerequisites associated with the $toolchains attribute.
    Optional<Attribute> toolchainAttribute =
        prerequisiteMap
            .keys()
            .stream()
            .filter(attribute -> attribute != null)
            .filter(attribute -> attribute.getName().equals(PlatformSemantics.TOOLCHAINS_ATTR))
            .findFirst();
    Preconditions.checkState(
        toolchainAttribute.isPresent(),
        "No toolchains attribute found while loading resolved toolchains");

    ImmutableMap.Builder<Label, ToolchainInfo> toolchains = new ImmutableMap.Builder<>();
    for (ConfiguredTargetAndData target : prerequisiteMap.get(toolchainAttribute.get())) {
      Label discoveredLabel = target.getTarget().getLabel();
      Label toolchainType = resolvedToolchainLabels.getType(discoveredLabel);
      if (toolchainType != null) {
        ToolchainInfo toolchainInfo = PlatformProviderUtils.toolchain(target.getConfiguredTarget());
        toolchains.put(toolchainType, toolchainInfo);
      }
    }

    return toolchains.build();
  }

  /** Tracks the mapping from toolchain type label to {@link ToolchainInfo} provider. */
  public class ResolvedToolchainProviders implements SkylarkValue, SkylarkIndexable {

    private final ImmutableMap<Label, ToolchainInfo> toolchains;

    private ResolvedToolchainProviders(ImmutableMap<Label, ToolchainInfo> toolchains) {
      this.toolchains = toolchains;
    }

    @Override
    public boolean isImmutable() {
      return true;
    }

    @Override
    public void repr(SkylarkPrinter printer) {
      printer.append("<toolchain_context.resolved_labels: ");
      printer.append(toolchains.keySet().stream()
          .map(key -> key.toString())
          .collect(joining(", ")));
      printer.append(">");
    }

    private Label transformKey(Object key, Location loc) throws EvalException {
      if (key instanceof Label) {
        Label toolchainType = (Label) key;
        return toolchainType;
      } else if (key instanceof String) {
        Label toolchainType = null;
        String rawLabel = (String) key;
        try {
          toolchainType = Label.parseAbsolute(rawLabel);
        } catch (LabelSyntaxException e) {
          throw new EvalException(
              loc, String.format("Unable to parse toolchain %s: %s", rawLabel, e.getMessage()), e);
        }
        return toolchainType;
      } else {
        throw new EvalException(
            loc,
            String.format(
                "Toolchains only supports indexing by toolchain type, got %s instead",
                EvalUtils.getDataTypeName(key)));
      }
    }

    @Override
    public ToolchainInfo getIndex(Object key, Location loc) throws EvalException {
      Label toolchainType = transformKey(key, loc);

      if (!requiredToolchains.contains(toolchainType)) {
        throw new EvalException(
            loc,
            String.format(
                "In %s, toolchain type %s was requested but only types [%s] are configured",
                targetDescription,
                toolchainType,
                requiredToolchains
                    .stream()
                    .map(toolchain -> toolchain.toString())
                    .collect(joining())));
      }
      return toolchains.get(toolchainType);
    }

    /** Returns the toolchain for the given type */
    public ToolchainInfo getForToolchainType(Label toolchainType) {
      return toolchains.get(toolchainType);
    }

    @Override
    public boolean containsKey(Object key, Location loc) throws EvalException {
      Label toolchainType = transformKey(key, loc);
      return toolchains.containsKey(toolchainType);
    }
  }
}
