// 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.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;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Starlark;

/**
 * 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) {
        throw new RepositoryFunctionException(
            Starlark.errorf(
                "Rule cannot have both a '%s' and '%s' attribute",
                getFileAttrName(), getFileContentAttrName()),
            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(
            Starlark.errorf(
                "the '%s' attribute does not specify a valid label: %s",
                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(
              Starlark.errorf("Unable to load package for %s: not found.", fileAttribute),
              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(
              Starlark.errorf(
                  "the '%s' attribute does not specify an existing file (%s does not exist)",
                  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(
            Starlark.errorf("%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 {
      throw new RepositoryFunctionException(
          Starlark.errorf("Rule requires a 'build_file' or 'build_file_content' attribute"),
          Transience.PERSISTENT);
    }
  }
}
