// Copyright 2014 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.skyframe;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.DependencyResolver;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.FragmentClassSet;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.NoSuchThingException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.skyframe.SkyFunction.Environment;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.ValueOrException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * A dependency resolver for use within Skyframe. Loads packages lazily when possible.
 */
public final class SkyframeDependencyResolver extends DependencyResolver {

  private final Environment env;

  public SkyframeDependencyResolver(Environment env) {
    this.env = env;
  }

  @Override
  protected void invalidVisibilityReferenceHook(TargetAndConfiguration value, Label label) {
    env.getListener().handle(
        Event.error(TargetUtils.getLocationMaybe(value.getTarget()), String.format(
            "Label '%s' in visibility attribute does not refer to a package group", label)));
  }

  @Override
  protected void invalidPackageGroupReferenceHook(TargetAndConfiguration value, Label label) {
    env.getListener().handle(
        Event.error(TargetUtils.getLocationMaybe(value.getTarget()), String.format(
            "label '%s' does not refer to a package group", label)));
  }

  @Override
  protected void missingEdgeHook(Target from, Label to, NoSuchThingException e)
      throws InterruptedException {
    if (e instanceof NoSuchTargetException) {
      NoSuchTargetException nste = (NoSuchTargetException) e;
      if (to.equals(nste.getLabel())) {
        env.getListener().handle(
            Event.error(
                TargetUtils.getLocationMaybe(from),
                TargetUtils.formatMissingEdge(from, to, e)));
      }
    } else if (e instanceof NoSuchPackageException) {
      NoSuchPackageException nspe = (NoSuchPackageException) e;
      if (nspe.getPackageId().equals(to.getPackageIdentifier())) {
        env.getListener().handle(
            Event.error(
                TargetUtils.getLocationMaybe(from),
                TargetUtils.formatMissingEdge(from, to, e)));
      }
    }
  }

  @Nullable
  @Override
  protected Target getTarget(Target from, Label label, NestedSetBuilder<Label> rootCauses)
      throws InterruptedException {
    SkyKey key = PackageValue.key(label.getPackageIdentifier());
    PackageValue packageValue;
    try {
      packageValue = (PackageValue) env.getValueOrThrow(key, NoSuchPackageException.class);
    } catch (NoSuchPackageException e) {
      rootCauses.add(label);
      missingEdgeHook(from, label, e);
      return null;
    }
    if (packageValue == null) {
      return null;
    }
    Package pkg = packageValue.getPackage();
    try {
      Target target = pkg.getTarget(label.getName());
      if (pkg.containsErrors()) {
        NoSuchTargetException e = new NoSuchTargetException(target);
        missingEdgeHook(from, label, e);
        if (target != null) {
          rootCauses.add(label);
          return target;
        } else {
          return null;
        }
      }
      return target;
    } catch (NoSuchTargetException e) {
      rootCauses.add(label);
      missingEdgeHook(from, label, e);
      return null;
    }
  }

  @Nullable
  @Override
  protected List<BuildConfiguration> getConfigurations(
      FragmentClassSet fragments,
      Iterable<BuildOptions> buildOptions,
      BuildOptions defaultBuildOptions)
      throws InvalidConfigurationException, InterruptedException {
    List<SkyKey> keys = new ArrayList<>();
    for (BuildOptions options : buildOptions) {
      keys.add(
          BuildConfigurationValue.key(
              fragments, BuildOptions.diffForReconstruction(defaultBuildOptions, options)));
    }
    Map<SkyKey, ValueOrException<InvalidConfigurationException>> configValues =
        env.getValuesOrThrow(keys, InvalidConfigurationException.class);
    if (env.valuesMissing()) {
      return null;
    }
    ImmutableList.Builder<BuildConfiguration> result = ImmutableList.builder();
    for (SkyKey key : keys) {
      result.add(((BuildConfigurationValue) configValues.get(key).get()).getConfiguration());
    }
    return result.build();
  }
}
