// Copyright 2016 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.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.FileValue;
import com.google.devtools.build.lib.actions.InconsistentFilesystemException;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
import com.google.devtools.build.lib.packages.BuildFileName;
import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
import com.google.devtools.build.lib.packages.ErrorDeterminingRepositoryException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Package.NameConflictException;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.packages.WorkspaceFileValue;
import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule;
import com.google.devtools.build.lib.skyframe.PackageFunction.PackageFunctionException;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
import javax.annotation.Nullable;

/** SkyFunction for {@link LocalRepositoryLookupValue}s. */
public class LocalRepositoryLookupFunction implements SkyFunction {

  @Override
  @Nullable
  public String extractTag(SkyKey skyKey) {
    return null;
  }

  // Implementation note: Although LocalRepositoryLookupValue.NOT_FOUND exists, it should never be
  // returned from this method.
  @Override
  public SkyValue compute(SkyKey skyKey, Environment env)
      throws SkyFunctionException, InterruptedException {
    RootedPath directory = (RootedPath) skyKey.argument();

    // Is this the root directory? If so, we're in the MAIN repository. This assumes that the main
    // repository has a WORKSPACE in the root directory, but Bazel will have failed with an error
    // before this can be called if that is incorrect.
    if (directory.getRootRelativePath().equals(PathFragment.EMPTY_FRAGMENT)) {
      return LocalRepositoryLookupValue.mainRepository();
    }

    // Does this directory contain a WORKSPACE file?
    Optional<Boolean> maybeWorkspaceFileExists = maybeGetWorkspaceFileExistence(env, directory);
    if (!maybeWorkspaceFileExists.isPresent()) {
      return null;
    } else if (maybeWorkspaceFileExists.get()) {
      Optional<LocalRepositoryLookupValue> maybeRepository =
          maybeCheckWorkspaceForRepository(env, directory);
      if (!maybeRepository.isPresent()) {
        return null;
      }
      LocalRepositoryLookupValue repository = maybeRepository.get();
      // If the repository that was discovered doesn't exist, continue recursing.
      if (repository.exists()) {
        return repository;
      }
    }

    // If we haven't found a repository yet, check the parent directory.
    return env.getValue(LocalRepositoryLookupValue.key(directory.getParentDirectory()));
  }

  private Optional<Boolean> maybeGetWorkspaceFileExistence(Environment env, RootedPath directory)
      throws InterruptedException, LocalRepositoryLookupFunctionException {
    try {
      RootedPath workspaceRootedFile =
          RootedPath.toRootedPath(
              directory.getRoot(),
              directory
                  .getRootRelativePath()
                  .getRelative(BuildFileName.WORKSPACE.getFilenameFragment()));
      FileValue workspaceFileValue =
          (FileValue) env.getValueOrThrow(FileValue.key(workspaceRootedFile), IOException.class);
      if (workspaceFileValue == null) {
        return Optional.absent();
      }
      if (workspaceFileValue.isDirectory()) {
        // There is a directory named WORKSPACE, ignore it for checking repository existence.
        return Optional.of(false);
      }
      return Optional.of(workspaceFileValue.exists());
    } catch (InconsistentFilesystemException e) {
      throw new LocalRepositoryLookupFunctionException(
          new ErrorDeterminingRepositoryException(
              "InconsistentFilesystemException while checking if there is a WORKSPACE file in "
                  + directory.asPath().getPathString(),
              e),
          Transience.PERSISTENT);
    } catch (FileSymlinkException e) {
      throw new LocalRepositoryLookupFunctionException(
          new ErrorDeterminingRepositoryException(
              "FileSymlinkException while checking if there is a WORKSPACE file in "
                  + directory.asPath().getPathString(),
              e),
          Transience.PERSISTENT);
    } catch (IOException e) {
      throw new LocalRepositoryLookupFunctionException(
          new ErrorDeterminingRepositoryException(
              "IOException while checking if there is a WORKSPACE file in "
                  + directory.asPath().getPathString(),
              e),
          Transience.PERSISTENT);
    }
  }

  /**
   * Checks whether the directory exists and is a workspace root. Returns {@link Optional#absent()}
   * if Skyframe needs to re-run, {@link Optional#of(LocalRepositoryLookupValue)} otherwise.
   */
  private Optional<LocalRepositoryLookupValue> maybeCheckWorkspaceForRepository(
      Environment env, final RootedPath directory)
      throws InterruptedException, LocalRepositoryLookupFunctionException {
    // Look up the main WORKSPACE file by the external package, to find all repositories.
    PackageLookupValue externalPackageLookupValue;
    try {
      externalPackageLookupValue =
          (PackageLookupValue)
              env.getValueOrThrow(
                  PackageLookupValue.key(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER),
                  BuildFileNotFoundException.class,
                  InconsistentFilesystemException.class);
      if (externalPackageLookupValue == null) {
        return Optional.absent();
      }
    } catch (BuildFileNotFoundException e) {
      throw new LocalRepositoryLookupFunctionException(
          new ErrorDeterminingRepositoryException(
              "BuildFileNotFoundException while loading the //external package", e),
          Transience.PERSISTENT);
    } catch (InconsistentFilesystemException e) {
      throw new LocalRepositoryLookupFunctionException(
          new ErrorDeterminingRepositoryException(
              "InconsistentFilesystemException while loading the //external package", e),
          Transience.PERSISTENT);
    }

    RootedPath workspacePath =
        externalPackageLookupValue.getRootedPath(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER);

    SkyKey workspaceKey = WorkspaceFileValue.key(workspacePath);
    do {
      WorkspaceFileValue value;
      try {
        value =
            (WorkspaceFileValue)
                env.getValueOrThrow(
                    workspaceKey, PackageFunctionException.class, NameConflictException.class);
        if (value == null) {
          return Optional.absent();
        }
      } catch (PackageFunctionException e) {
        // TODO(jcater): When WFF is rewritten to not throw a PFE, update this.
        throw new LocalRepositoryLookupFunctionException(
            new ErrorDeterminingRepositoryException(
                "PackageFunctionException while loading the root WORKSPACE file", e),
            Transience.PERSISTENT);
      } catch (NameConflictException e) {
        throw new LocalRepositoryLookupFunctionException(
            new ErrorDeterminingRepositoryException(
                "NameConflictException while loading the root WORKSPACE file", e),
            Transience.PERSISTENT);
      }

      Package externalPackage = value.getPackage();
      if (externalPackage.containsErrors()) {
        Event.replayEventsOn(env.getListener(), externalPackage.getEvents());
      }

      // Find all local_repository rules in the WORKSPACE, and check if any have a "path" attribute
      // the same as the requested directory.
      Iterable<Rule> localRepositories =
          externalPackage.getRulesMatchingRuleClass(LocalRepositoryRule.NAME);
      Rule rule =
          Iterables.find(
              localRepositories,
              new Predicate<Rule>() {
                @Override
                public boolean apply(@Nullable Rule rule) {
                  AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
                  // Construct the path. If not absolute, it will be relative to the workspace.
                  Path localPath =
                      workspacePath.getRoot().getRelative(mapper.get("path", Type.STRING));
                  return directory.asPath().equals(localPath);
                }
              },
              null);
      if (rule != null) {
        try {
          String path = (String) rule.getAttributeContainer().getAttr("path");
          return Optional.of(
              LocalRepositoryLookupValue.success(
                  RepositoryName.create("@" + rule.getName()), PathFragment.create(path)));
        } catch (LabelSyntaxException e) {
          // This shouldn't be possible if the rule name is valid, and it should already have been
          // validated.
          throw new LocalRepositoryLookupFunctionException(
              new ErrorDeterminingRepositoryException(
                  "LabelSyntaxException while creating the repository name from the rule "
                      + rule.getName(),
                  e),
              Transience.PERSISTENT);
        }
      }
      workspaceKey = value.next();

      // TODO(bazel-team): This loop can be quadratic in the number of load() statements, consider
      // rewriting or unrolling.
    } while (workspaceKey != null);

    return Optional.of(LocalRepositoryLookupValue.notFound());
  }

  /**
   * Used to declare all the exception types that can be wrapped in the exception thrown by {@link
   * LocalRepositoryLookupFunction#compute}.
   */
  private static final class LocalRepositoryLookupFunctionException extends SkyFunctionException {
    public LocalRepositoryLookupFunctionException(
        ErrorDeterminingRepositoryException e, Transience transience) {
      super(e, transience);
    }
  }
}
