// Copyright 2019 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.blackbox.tests.workspace;

import com.google.devtools.build.lib.blackbox.framework.PathUtils;
import java.io.IOException;
import java.nio.file.Path;

/**
 * Generator of the test local repository with:
 *
 * <p>helper.bzl file, that contains a write_to_file rule, which writes some text to the output
 * file.
 *
 * <p>empty WORKSPACE file,
 *
 * <p>BUILD file, with write_to_file target and pkg_tar target for packing the contents of the
 * generated repository.
 *
 * <p>Intended to be used by workspace tests.
 */
public class RepoWithRuleWritingTextGenerator {

  static final String HELPER_FILE = "helper.bzl";
  static final String RULE_NAME = "write_to_file";
  static final String HELLO = "HELLO";
  static final String TARGET = "write_text";
  static final String OUT_FILE = "out";

  static final String WRITE_TEXT_TO_FILE =
      "def _impl(ctx):\n"
          + "  out = ctx.actions.declare_file(ctx.attr.filename)\n"
          + "  ctx.actions.write(out, ctx.attr.text)\n"
          + "  return [DefaultInfo(files = depset([out]))]\n"
          + "\n"
          + RULE_NAME
          + " = rule(\n"
          + "    implementation = _impl,\n"
          + "    attrs = {\n"
          + "        \"filename\": attr.string(default = \"out\"),\n"
          + "        \"text\": attr.string()\n"
          + "    }\n"
          + ")";

  private final Path root;
  private String target;
  private String outputText;
  private String outFile;

  /**
   * Generator constructor
   *
   * @param root - the Path to the directory, where the repository contents should be placed
   */
  RepoWithRuleWritingTextGenerator(Path root) {
    this.root = root;
    this.target = TARGET;
    this.outputText = HELLO;
    this.outFile = OUT_FILE;
  }

  /**
   * Specifies the text to be put into generated file by write_to_file rule target
   *
   * @param text - text to be put into a file
   * @return this generator
   */
  RepoWithRuleWritingTextGenerator withOutputText(String text) {
    outputText = text;
    return this;
  }

  /**
   * Specifies the name of the write_to_file target in the generated repository
   *
   * @param name - name of the target
   * @return this generator
   */
  RepoWithRuleWritingTextGenerator withTarget(String name) {
    target = name;
    return this;
  }

  /**
   * Specifies the output file name of the write_to_file rule target
   *
   * @param name - output file name
   * @return this generator
   */
  RepoWithRuleWritingTextGenerator withOutFile(String name) {
    outFile = name;
    return this;
  }

  /**
   * Generates the repository: WORKSPACE, BUILD, and helper.bzl files.
   *
   * @return repository directory
   * @throws IOException if was not able to create or write to files
   */
  Path setupRepository() throws IOException {
    Path workspace = PathUtils.writeFileInDir(root, "WORKSPACE");
    PathUtils.writeFileInDir(root, HELPER_FILE, WRITE_TEXT_TO_FILE);
    PathUtils.writeFileInDir(
        root,
        "BUILD",
        "load(\"@bazel_tools//tools/build_defs/pkg:pkg.bzl\", \"pkg_tar\")",
        loadRule(""),
        callRule(target, outFile, outputText),
        String.format("pkg_tar(name = \"%s\", srcs = glob([\"*\"]),)", getPkgTarTarget()));
    return workspace.getParent();
  }

  /**
   * Returns the text to be put into a header of Starlark file, which is going to use write_to_file
   * rule from the @repoName repository
   *
   * @param repoName the name of the repository
   * @return load statement text
   */
  static String loadRule(String repoName) {
    return String.format("load('%s//:%s', '%s')", repoName, HELPER_FILE, RULE_NAME);
  }

  /**
   * Returns the text with the write_to_file target
   *
   * @param name target name
   * @param filename name of the output file
   * @param text text to be put into output file
   * @return the write_to_file target definition
   */
  static String callRule(String name, String filename, String text) {
    return String.format(
        "%s(name = '%s', filename = '%s', text ='%s')", RULE_NAME, name, filename, text);
  }

  /** @return name of the generated pkg_tar target */
  String getPkgTarTarget() {
    return "pkg_tar_" + target;
  }
}
