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

import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.FileValue;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.LabelValidator;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
import com.google.devtools.build.lib.skyframe.PackageLookupValue;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
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.io.IOException;
import java.util.Map;

/**
 * Encapsulates the 2-step behavior of creating workspace and build files for the new_*_repository
 * rules.
 */
public class NewRepositoryFileHandler {

  private NewRepositoryWorkspaceFileHandler workspaceFileHandler;
  private NewRepositoryBuildFileHandler buildFileHandler;

  public NewRepositoryFileHandler(Path workspacePath) {
    this.workspaceFileHandler = new NewRepositoryWorkspaceFileHandler(workspacePath);
    this.buildFileHandler = new NewRepositoryBuildFileHandler(workspacePath);
  }

  public boolean prepareFile(Rule rule, Environment env)
      throws RepositoryFunctionException, InterruptedException {
    if (!this.workspaceFileHandler.prepareFile(rule, env)) {
      return false;
    }
    if (!this.buildFileHandler.prepareFile(rule, env)) {
      return false;
    }

    return true;
  }

  public void finishFile(Rule rule, Path outputDirectory, Map<String, String> markerData)
      throws RepositoryFunctionException {
    this.workspaceFileHandler.finishFile(rule, outputDirectory, markerData);
    this.buildFileHandler.finishFile(rule, outputDirectory, markerData);
  }

  /**
   * Encapsulates the 2-step behavior of creating files for the new_*_repository rules, based on a
   * pair of attributes defined in {@link #getFileAttrName()} and {@link #getFileContentAttrName()}.
   */
  private abstract static class BaseFileHandler {

    private final Path workspacePath;
    private final String filename;
    private FileValue fileValue;
    private String fileContent;

    private BaseFileHandler(Path workspacePath, String filename) {
      this.workspacePath = workspacePath;
      this.filename = filename;
    }

    protected abstract String getFileAttrName();

    protected abstract String getFileContentAttrName();

    protected abstract String getDefaultContent(Rule rule) throws RepositoryFunctionException;

    /**
     * Prepares for writing a file by validating the FOO_file and FOO_file_content attributes of the
     * rule.
     *
     * @return true if the file was successfully created, false if the environment is missing values
     *     (the calling fetch() function should return null in this case).
     * @throws RepositoryFunctionException if the rule does defines both the FOO_file and
     *     FOO_file_content attributes, or if the workspace file could not be retrieved, written, or
     *     symlinked.
     */
    public boolean prepareFile(Rule rule, Environment env)
        throws RepositoryFunctionException, InterruptedException {

      WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
      boolean hasFile = mapper.isAttributeValueExplicitlySpecified(getFileAttrName());
      boolean hasFileContent = mapper.isAttributeValueExplicitlySpecified(getFileContentAttrName());

      if (hasFile && hasFileContent) {

        String error =
            String.format(
                "Rule %s cannot have both a '%s' and '%s' attribute",
                rule, getFileAttrName(), getFileContentAttrName());
        throw new RepositoryFunctionException(
            new EvalException(rule.getLocation(), error), Transience.PERSISTENT);

      } else if (hasFile) {

        fileValue = getFileValue(rule, env);
        if (env.valuesMissing()) {
          return false;
        }

      } else if (hasFileContent) {

        try {
          fileContent = mapper.get(getFileContentAttrName(), Type.STRING);
        } catch (EvalException e) {
          throw new RepositoryFunctionException(e, Transience.PERSISTENT);
        }

      } else {
        fileContent = getDefaultContent(rule);
      }

      return true;
    }

    /**
     * Writes the file, based on the state set by prepareFile().
     *
     * @param outputDirectory the directory to write the file.
     * @throws RepositoryFunctionException if the file could not be written or symlinked
     * @throws IllegalStateException if {@link #prepareFile} was not called before this, or if
     *     {@link #prepareFile} failed and this was called.
     */
    public void finishFile(Rule rule, Path outputDirectory, Map<String, String> markerData)
        throws RepositoryFunctionException {
      if (fileValue != null) {
        // Link x/FILENAME to <build_root>/x.FILENAME.
        symlinkFile(fileValue, filename, outputDirectory);
        String fileAttribute = getFileAttributeValue(rule);
        String fileKey;
        if (LabelValidator.isAbsolute(fileAttribute)) {
          fileKey = getFileAttributeAsLabel(rule).toString();
        } else {
          // TODO(pcloudy): Don't add absolute path into markerData once it's not supported
          fileKey = fileValue.realRootedPath().asPath().getPathString();
        }
        try {
          markerData.put("FILE:" + fileKey, RepositoryFunction.fileValueToMarkerValue(fileValue));
        } catch (IOException e) {
          throw new RepositoryFunctionException(e, Transience.TRANSIENT);
        }
      } else if (fileContent != null) {
        RepositoryFunction.writeFile(outputDirectory, filename, fileContent);
      } else {
        throw new IllegalStateException("prepareFile() must be called before finishFile()");
      }
    }

    private String getFileAttributeValue(Rule rule) throws RepositoryFunctionException {
      WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
      String fileAttribute;
      try {
        fileAttribute = mapper.get(getFileAttrName(), Type.STRING);
      } catch (EvalException e) {
        throw new RepositoryFunctionException(e, Transience.PERSISTENT);
      }
      return fileAttribute;
    }

    private Label getFileAttributeAsLabel(Rule rule) throws RepositoryFunctionException {
      Label label;
      try {
        // Parse a label
        label = Label.parseAbsolute(getFileAttributeValue(rule), ImmutableMap.of());
      } catch (LabelSyntaxException ex) {
        throw new RepositoryFunctionException(
            new EvalException(
                rule.getLocation(),
                String.format(
                    "In %s the '%s' attribute does not specify a valid label: %s",
                    rule, getFileAttrName(), ex.getMessage())),
            Transience.PERSISTENT);
      }
      return label;
    }

    private FileValue getFileValue(Rule rule, Environment env)
        throws RepositoryFunctionException, InterruptedException {
      String fileAttribute = getFileAttributeValue(rule);
      RootedPath rootedFile;

      if (LabelValidator.isAbsolute(fileAttribute)) {
        Label label = getFileAttributeAsLabel(rule);
        SkyKey pkgSkyKey = PackageLookupValue.key(label.getPackageIdentifier());
        PackageLookupValue pkgLookupValue = (PackageLookupValue) env.getValue(pkgSkyKey);
        if (pkgLookupValue == null) {
          return null;
        }
        if (!pkgLookupValue.packageExists()) {
          throw new RepositoryFunctionException(
              new EvalException(
                  rule.getLocation(),
                  "Unable to load package for " + fileAttribute + ": not found."),
              Transience.PERSISTENT);
        }

        // And now for the file
        Root packageRoot = pkgLookupValue.getRoot();
        rootedFile = RootedPath.toRootedPath(packageRoot, label.toPathFragment());
      } else {
        // TODO(dmarting): deprecate using a path for the workspace_file attribute.
        PathFragment file = PathFragment.create(fileAttribute);
        Path fileTarget = workspacePath.getRelative(file);
        if (!fileTarget.exists()) {
          throw new RepositoryFunctionException(
              new EvalException(
                  rule.getLocation(),
                  String.format(
                      "In %s the '%s' attribute does not specify an existing file "
                          + "(%s does not exist)",
                      rule, getFileAttrName(), fileTarget)),
              Transience.PERSISTENT);
        }

        if (file.isAbsolute()) {
          rootedFile =
              RootedPath.toRootedPath(
                  Root.fromPath(fileTarget.getParentDirectory()),
                  PathFragment.create(fileTarget.getBaseName()));
        } else {
          rootedFile = RootedPath.toRootedPath(Root.fromPath(workspacePath), file);
        }
      }
      SkyKey fileKey = FileValue.key(rootedFile);
      FileValue fileValue;
      try {
        // Note that this dependency is, strictly speaking, not necessary: the symlink could simply
        // point to this FileValue and the symlink chasing could be done while loading the package
        // but this results in a nicer error message and it's correct as long as RepositoryFunctions
        // don't write to things in the file system this FileValue depends on. In theory, the latter
        // is possible if the file referenced by workspace_file is a symlink to somewhere under the
        // external/ directory, but if you do that, you are really asking for trouble.
        fileValue = (FileValue) env.getValueOrThrow(fileKey, IOException.class);
        if (fileValue == null) {
          return null;
        }
      } catch (IOException e) {
        throw new RepositoryFunctionException(
            new IOException("Cannot lookup " + fileAttribute + ": " + e.getMessage()),
            Transience.TRANSIENT);
      }

      if (!fileValue.isFile() || fileValue.isSpecialFile()) {
        throw new RepositoryFunctionException(
            new EvalException(
                rule.getLocation(), String.format("%s is not a regular file", rootedFile.asPath())),
            Transience.PERSISTENT);
      }

      return fileValue;
    }

    /**
     * Symlinks a file from the local filesystem into the external repository's root.
     *
     * @param fileValue {@link FileValue} representing the file to be linked in
     * @param outputDirectory the directory of the remote repository
     * @throws RepositoryFunctionException if the file specified does not exist or cannot be linked.
     */
    private static void symlinkFile(FileValue fileValue, String filename, Path outputDirectory)
        throws RepositoryFunctionException {
      Path filePath = outputDirectory.getRelative(filename);
      RepositoryFunction.createSymbolicLink(filePath, fileValue.realRootedPath().asPath());
    }
  }

  /**
   * Encapsulates the 2-step behavior of creating workspace files for the new_*_repository rules.
   */
  public static class NewRepositoryWorkspaceFileHandler extends BaseFileHandler {

    public NewRepositoryWorkspaceFileHandler(Path workspacePath) {
      super(workspacePath, "WORKSPACE");
    }

    @Override
    protected String getFileAttrName() {
      return "workspace_file";
    }

    @Override
    protected String getFileContentAttrName() {
      return "workspace_file_content";
    }

    @Override
    protected String getDefaultContent(Rule rule) {
      return String.format(
          "# DO NOT EDIT: automatically generated WORKSPACE file for %s\n"
              + "workspace(name = \"%s\")\n",
          rule.getTargetKind(), rule.getName());
    }
  }

  /** Encapsulates the 2-step behavior of creating build files for the new_*_repository rules. */
  public static class NewRepositoryBuildFileHandler extends BaseFileHandler {

    public NewRepositoryBuildFileHandler(Path workspacePath) {
      super(workspacePath, "BUILD.bazel");
    }

    @Override
    protected String getFileAttrName() {
      return "build_file";
    }

    @Override
    protected String getFileContentAttrName() {
      return "build_file_content";
    }

    @Override
    protected String getDefaultContent(Rule rule) throws RepositoryFunctionException {
      String error =
          String.format("Rule %s requires a 'build_file' or 'build_file_content' attribute", rule);
      throw new RepositoryFunctionException(
          new EvalException(rule.getLocation(), error), Transience.PERSISTENT);
    }
  }
}
