// 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.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.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.repository.ExternalPackageUtil;
import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule;
import com.google.devtools.build.lib.rules.repository.WorkspaceFileHelper;
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 = WorkspaceFileHelper.getWorkspaceRootedFile(directory, env);
      if (workspaceRootedFile == null) {
        return Optional.absent();
      }
      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 {
    RootedPath workspacePath = ExternalPackageUtil.findWorkspaceFile(env);
    if (env.valuesMissing()) {
      return Optional.absent();
    }

    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 =
          Iterables.filter(
              externalPackage.getTargets(Rule.class),
              rule -> LocalRepositoryRule.NAME.equals(rule.getRuleClass()));
      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);
    }
  }
}
