// 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.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.rules.repository.RepositoryFunction.RepositoryFunctionException;
import com.google.devtools.build.lib.skyframe.FileValue;
import com.google.devtools.build.lib.skyframe.PackageLookupValue;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Type;
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));
      } 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);
    }
  }
}
