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

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.WorkspaceFileValue;
import com.google.devtools.build.lib.skyframe.PackageLookupValue;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.SkyFunction.Environment;
import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
import com.google.devtools.build.skyframe.SkyKey;
import java.util.List;
import javax.annotation.Nullable;

/** Utility class to centralize looking up rules from the external package. */
public class ExternalPackageUtil {

  /**
   * Loads the external package and then calls the selector to find matching rules.
   *
   * @param env the environment to use for lookups
   * @param returnFirst whether to return only the first rule found
   * @param selector the function to call to load rules
   */
  @Nullable
  private static List<Rule> getRules(
      Environment env, boolean returnFirst, Function<Package, List<Rule>> selector)
      throws ExternalPackageException, InterruptedException {
    SkyKey packageLookupKey = PackageLookupValue.key(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER);
    PackageLookupValue packageLookupValue = (PackageLookupValue) env.getValue(packageLookupKey);
    if (packageLookupValue == null) {
      return null;
    }
    RootedPath workspacePath =
        packageLookupValue.getRootedPath(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER);

    List<Rule> rules = returnFirst ? ImmutableList.of() : Lists.newArrayList();
    SkyKey workspaceKey = WorkspaceFileValue.key(workspacePath);
    do {
      WorkspaceFileValue value = (WorkspaceFileValue) env.getValue(workspaceKey);
      if (value == null) {
        return null;
      }
      Package externalPackage = value.getPackage();
      if (externalPackage.containsErrors()) {
        Event.replayEventsOn(env.getListener(), externalPackage.getEvents());
        throw new ExternalPackageException(
            new BuildFileContainsErrorsException(
                LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER, "Could not load //external package"),
            Transience.PERSISTENT);
      }
      List<Rule> results = selector.apply(externalPackage);
      if (results != null && !results.isEmpty()) {
        if (returnFirst) {
          // assert expected non null value explicitly for possible future callers
          return ImmutableList.of(Preconditions.checkNotNull(results.get(0)));
        }
        rules.addAll(results);
      }
      workspaceKey = value.next();
    } while (workspaceKey != null);

    return rules;
  }

  /** Uses a rule name to fetch the corresponding Rule from the external package. */
  @Nullable
  public static Rule getRuleByName(final String ruleName, Environment env)
      throws ExternalPackageException, InterruptedException {

    List<Rule> rules =
        getRules(
            env,
            true,
            new Function<Package, List<Rule>>() {
              @Nullable
              @Override
              public List<Rule> apply(Package externalPackage) {
                Rule rule = externalPackage.getRule(ruleName);
                if (rule == null) {
                  return null;
                }
                return ImmutableList.of(rule);
              }
            });

    if (env.valuesMissing()) {
      return null;
    }
    if (rules == null || rules.isEmpty()) {
      throw new ExternalRuleNotFoundException(ruleName);
    }
    return Iterables.getFirst(rules, null);
  }
}
