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

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.PackageLoadingListener;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.skyframe.packages.BazelPackageLoader;
import com.google.devtools.build.lib.skyframe.packages.PackageLoader;
import com.google.devtools.build.lib.vfs.Root;
import net.starlark.java.eval.StarlarkSemantics;

/**
 * A {@link PackageLoadingListener} for use in tests that a check with {@link BazelPackageLoader}
 * for each loaded package, for the sake of getting pretty nice test coverage.
 */
public class BazelPackageLoadingListenerForTesting implements PackageLoadingListener {
  private final ConfiguredRuleClassProvider ruleClassProvider;
  private final BlazeDirectories directories;

  public BazelPackageLoadingListenerForTesting(
      ConfiguredRuleClassProvider ruleClassProvider, BlazeDirectories directories) {
    this.ruleClassProvider = ruleClassProvider;
    this.directories = directories;
  }

  @Override
  public void onLoadingCompleteAndSuccessful(
      Package pkg, StarlarkSemantics starlarkSemantics, long loadTimeNanos) {
    sanityCheckBazelPackageLoader(pkg, ruleClassProvider, starlarkSemantics);
  }

  private PackageLoader makeFreshPackageLoader(
      ConfiguredRuleClassProvider ruleClassProvider, StarlarkSemantics starlarkSemantics) {
    return BazelPackageLoader.builder(
            Root.fromPath(directories.getWorkspace()),
            directories.getInstallBase(),
            directories.getOutputBase())
        .setStarlarkSemantics(starlarkSemantics)
        .setRuleClassProvider(ruleClassProvider)
        .build();
  }

  private void sanityCheckBazelPackageLoader(
      Package pkg,
      ConfiguredRuleClassProvider ruleClassProvider,
      StarlarkSemantics starlarkSemantics) {
    PackageIdentifier pkgId = pkg.getPackageIdentifier();
    Package newlyLoadedPkg;
    try (PackageLoader packageLoader =
        makeFreshPackageLoader(ruleClassProvider, starlarkSemantics)) {
      newlyLoadedPkg = packageLoader.loadPackage(pkg.getPackageIdentifier());
    } catch (InterruptedException e) {
      return;
    } catch (NoSuchPackageException e) {
      throw new IllegalStateException(e);
    }
    ImmutableSet<Label> targetsInPkg =
        ImmutableSet.copyOf(Iterables.transform(pkg.getTargets().values(), Target::getLabel));
    ImmutableSet<Label> targetsInNewlyLoadedPkg =
        ImmutableSet.copyOf(
            Iterables.transform(newlyLoadedPkg.getTargets().values(), Target::getLabel));
    if (!targetsInPkg.equals(targetsInNewlyLoadedPkg)) {
      Sets.SetView<Label> unsatisfied = Sets.difference(targetsInPkg, targetsInNewlyLoadedPkg);
      Sets.SetView<Label> unexpected = Sets.difference(targetsInNewlyLoadedPkg, targetsInPkg);
      throw new IllegalStateException(
          String.format(
              "The Package for %s had a different set of targets (<targetsInPkg> - "
                  + "<targetsInNewlyLoadedPkg> = %s, <targetsInNewlyLoadedPkg> - <targetsInPkg> = "
                  + "%s) when loaded normally during execution of the current test than it did "
                  + "when loaded via BazelPackageLoader (done automatically by the "
                  + "BazelPackageLoadingListenerForTesting hook). This either means: (i) Skyframe "
                  + "package loading semantics have diverged from "
                  + "BazelPackageLoader semantics (ii) The test in question is doing something "
                  + "that confuses BazelPackageLoadingListenerForTesting.",
              pkgId, unsatisfied, unexpected));
    }
  }
}
