// Copyright 2017 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.genrule;

import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.BuildType.LICENSE;
import static com.google.devtools.build.lib.packages.BuildType.OUTPUT_LIST;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import static com.google.devtools.build.lib.syntax.Type.STRING;

import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.analysis.config.HostTransition;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.RuleClass.ExecutionPlatformConstraintsAllowed;
import com.google.devtools.build.lib.util.FileTypeSet;

/**
 * Rule definition for the genrule rule, intended to be inherited by specific GenRule
 * implementations. Implementations will need to include any needed additional dependencies, such
 * as a setup script target.
 */
public class GenRuleBaseRule implements RuleDefinition {

  @Override
  public RuleClass build(
      RuleClass.Builder builder, RuleDefinitionEnvironment env) {
    return builder

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(srcs) -->
        A list of inputs for this rule, such as source files to process.
        <p>
          <em>This attributes is not suitable to list tools executed by the <code>cmd</code>; use
          the <a href="${link genrule.tools}"><code>tools</code></a> attribute for them instead.
          </em>
        </p>
        <p>
          The build system ensures these prerequisites are built before running the genrule
          command; they are built using the same configuration as the original build request. The
          names of the files of these prerequisites are available to the command as a
          space-separated list in <code>$(SRCS)</code>; alternatively the path of an individual
          <code>srcs</code> target <code>//x:y</code> can be obtained using <code>$(location
          //x:y)</code>, or using <code>$&lt;</code> provided it's the only entry in
          //<code>srcs</code>.
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(
            attr("srcs", LABEL_LIST)
                .direct_compile_time_input()
                .allowedFileTypes(FileTypeSet.ANY_FILE))

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(tools) -->
        A list of <i>tool</i> dependencies for this rule. See the definition of
        <a href="../build-ref.html#deps">dependencies</a> for more information. <br/>
        <p>
          The build system ensures these prerequisites are built before running the genrule command;
          they are built using the <a href='../user-manual.html#configurations'><i>host</i>
          configuration</a>, since these tools are executed as part of the build. The path of an
          individual <code>tools</code> target <code>//x:y</code> can be obtained using
          <code>$(location //x:y)</code>.
        </p>
        <p>
          Any <code>*_binary</code> or tool to be executed by <code>cmd</code> must appear in this
          list, not in <code>srcs</code>, to ensure they are built in the correct configuration.
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(
            attr("tools", LABEL_LIST)
                .cfg(HostTransition.createFactory())
                .allowedFileTypes(FileTypeSet.ANY_FILE))
        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(outs) -->
        A list of files generated by this rule.
        <p>
          Output files must not cross package boundaries.
          Output filenames are interpreted as relative to the package.
        </p>
        <p>
          If the <code>executable</code> flag is set, <code>outs</code> must contain exactly one
          label.
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("outs", OUTPUT_LIST).mandatory())

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(cmd) -->
        The command to run.
        Subject to <a href="${link make-variables#location}">$(location)</a> and
        <a href="${link make-variables}">"Make" variable</a> substitution.
        <ol>
          <li>
            First <a href="${link make-variables#location}">$(location)</a> substitution is
            applied, replacing all occurrences of <code>$(location <i>label</i>)</code> and of
            <code>$(locations <i>label</i>)</code>.
          </li>
          <li>
            <p>
              Note that <code>outs</code> are <i>not</i> included in this substitution. Output files
              are always generated into a predictable location (available via <code>$(@D)</code>,
              <code>$@</code>, <code>$(OUTS)</code> or <code>$(RULEDIR)</code> or
              <code>$(location <i>output_name</i>)</code>; see below).
            </p>
          </li>
          <li>
            Next, <a href="${link make-variables}">"Make" variables</a> are expanded. Note that
            predefined variables <code>$(JAVA)</code>, <code>$(JAVAC)</code> and
            <code>$(JAVABASE)</code> expand under the <i>host</i> configuration, so Java invocations
            that run as part of a build step can correctly load shared libraries and other
            dependencies.
          </li>
          <li>
            Finally, the resulting command is executed using the Bash shell. If its exit code is
            non-zero the command is considered to have failed.
          </li>
        </ol>
        <p>
          The command may refer to <code>*_binary</code> targets; it should use a <a
          href="../build-ref.html#labels">label</a> for this. The following
          variables are available within the <code>cmd</code> sublanguage:</p>
        <ul>
          <li>
            <a href="${link make-variables#predefined_variables.genrule.cmd}">"Make" variables</a>
          </li>
          <li>
            "Make" variables that are predefined by the build tools.
            Please use these variables instead of hardcoded values.
            See <a href="${link make-variables#predefined_variables}">Predefined "Make" Variables
            </a> in this document for a list of supported values.
          </li>
        </ul>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("cmd", STRING).mandatory())

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(output_to_bindir) -->
        <p>
          If set to 1, this option causes output files to be written into the <code>bin</code>
          directory instead of the <code>genfiles</code> directory.
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        // TODO(bazel-team): find a location to document genfiles/binfiles, link to them from here.
        .add(
            attr("output_to_bindir", BOOLEAN)
                .value(false)
                .nonconfigurable(
                    "policy decision: no reason for this to depend on the configuration"))

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(local) -->
        <p>
          If set to 1, this option force this <code>genrule</code> to run with the
          <code>standalone</code> strategy, without sandboxing.
        </p>
        <p>
          This is equivalent to providing 'local' as a tag (<code>tags=["local"]</code>). The
          local strategy is applied if either one is specified.
        </p>
        <p>
          The <code>--genrule_strategy</code> option value <code>local</code>
          overrides this attribute.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("local", BOOLEAN).value(false))

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(message) -->
        A progress message.
        <p>
          A progress message that will be printed as this build step is executed. By default, the
          message is "Generating <i>output</i>" (or something equally bland) but you may provide a
          more specific one. Use this attribute instead of <code>echo</code> or other print
          statements in your <code>cmd</code> command, as this allows the build tool to control
          whether such progress messages are printed or not.
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("message", STRING))
        /*<!-- #BLAZE_RULE(genrule).ATTRIBUTE(output_licenses) -->
        See <a href="${link common-definitions#binary.output_licenses}"><code>common attributes
        </code></a>
        <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
        .add(attr("output_licenses", LICENSE))

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(executable) -->
        Declare output to be executable.
        <p>
          Setting this flag to 1 means the output is an executable file and can be run using the
          <code>run</code> command. The genrule must produce exactly one output in this case.
          If this attribute is set, <code>run</code> will try executing the file regardless of
          its content.
        </p>
        <p>Declaring data dependencies for the generated executable is not supported.</p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(
            attr("executable", BOOLEAN)
                .value(false)
                .nonconfigurable(
                    "Used in computed default for $is_executable, which is itself non-configurable"
                        + " (and thus expects its dependencies to be non-configurable), because"
                        + " $is_executable  is called from RunCommand.isExecutable, which has no"
                        + " configuration context"))
        .add(
            attr("$is_executable", BOOLEAN)
                .nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")
                .value(
                    new Attribute.ComputedDefault() {
                      @Override
                      public Object getDefault(AttributeMap rule) {
                        return (rule.get("outs", BuildType.OUTPUT_LIST).size() == 1)
                            && rule.get("executable", BOOLEAN);
                      }
                    }))

        // This is a misfeature, so don't document it. We would like to get rid of it, but that
        // would require a cleanup of existing rules.
        .add(attr("heuristic_label_expansion", BOOLEAN).value(false))
        .removeAttribute("data")
        .removeAttribute("deps")
        .executionPlatformConstraintsAllowed(ExecutionPlatformConstraintsAllowed.PER_TARGET)
        .build();
  }

  @Override
  public RuleDefinition.Metadata getMetadata() {
    return RuleDefinition.Metadata.builder()
        .name("$genrule_base")
        .type(RuleClassType.ABSTRACT)
        .ancestors(BaseRuleClasses.RuleBase.class, BaseRuleClasses.MakeVariableExpandingRule.class)
        .build();
  }
}
