// 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.packages.Type.BOOLEAN;
import static com.google.devtools.build.lib.packages.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.ExecutionTransitionFactory;
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.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="${link build-ref#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='${link guide#configurations}'><i>exec</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(ExecutionTransitionFactory.create())
                .allowedFileTypes(FileTypeSet.ANY_FILE))

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(exec_tools) -->
        <b>Deprecated. Use <code>tools</code> instead.</b>

        <p>
          A list of <i>tool</i> dependencies for this rule. This behaves exactly like the
          <a href="#genrule.tools"><code>tools</code></a> attribute, except that these dependencies
          will be configured for the rule's execution platform instead of the exec configuration.
          This means that dependencies in <code>exec_tools</code> are not subject to the same
          limitations as dependencies in <code>tools</code>. In particular, they are not required to
          use the exec configuration for their own transitive dependencies. See
          <a href="#genrule.tools"><code>tools</code></a> for further details.
        </p>

        <p>
          The Blaze team has finished cleaning up users of the host transition, and now is migrating
          users back to use <code>tools</code>.
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(
            attr("exec_tools", LABEL_LIST)
                .cfg(ExecutionTransitionFactory.create())
                .allowedFileTypes(FileTypeSet.ANY_FILE)
                .dontCheckConstraints())

        /* <!-- #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>
        <p>
          The genrule command is expected to create each output file at a predetermined location.
          The location is available in <code>cmd</code> using <a
          href="${link make-variables#predefined_genrule_variables}">genrule-specific "Make"
          variables</a> (<code>$@</code>, <code>$(OUTS)</code>, <code>$(@D)</code> or <code>
          $(RULEDIR)</code>) or using <a href="${link make-variables#predefined_label_variables}">
          <code>$(location)</code></a> substitution.
        </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#predefined_label_variables}"><code>$(location)
        </code></a> and <a href="${link make-variables}">"Make" variable</a> substitution.
        <ol>
          <li>
            First <a href="${link make-variables#predefined_label_variables}"><code>$(location)
            </code></a> substitution is applied, replacing all occurrences of <code>$(location <i>
            label</i>)</code> and of <code>$(locations <i>label</i>)</code> (and similar
            constructions using related variables <code>execpath</code>, <code>execpaths</code>,
            <code>rootpath</code> and <code>rootpaths</code>).
          </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>exec</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>
        This is the fallback of <code>cmd_bash</code>, <code>cmd_ps</code> and <code>cmd_bat</code>,
        if none of them are applicable.
        </p>
        <p>
        If the command line length exceeds the platform limit (64K on Linux/macOS, 8K on Windows),
        then genrule will write the command to a script and execute that script to work around. This
        applies to all cmd attributes (<code>cmd</code>, <code>cmd_bash</code>, <code>cmd_ps</code>,
        <code>cmd_bat</code>).
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("cmd", STRING))

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(cmd_bash) -->
        The Bash command to run.
        <p> This attribute has higher priority than <code>cmd</code>. The command is expanded and
            runs in the exact same way as the <code>cmd</code> attribute.
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("cmd_bash", STRING))

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(cmd_bat) -->
        The Batch command to run on Windows.
        <p> This attribute has higher priority than <code>cmd</code> and <code>cmd_bash</code>.
            The command runs in the similar way as the <code>cmd</code> attribute, with the
            following differences:
        </p>
        <ul>
          <li>
            This attribute only applies on Windows.
          </li>
          <li>
            The command runs with <code>cmd.exe /c</code> with the following default arguments:
            <ul>
              <li>
                <code>/S</code> - strip first and last quotes and execute everything else as is.
              </li>
              <li>
                <code>/E:ON</code> - enable extended command set.
              </li>
              <li>
                <code>/V:ON</code> - enable delayed variable expansion
              </li>
              <li>
                <code>/D</code> - ignore AutoRun registry entries.
              </li>
            </ul>
          </li>
          <li>
            After <a href="${link make-variables#predefined_label_variables}">$(location)</a> and
            <a href="${link make-variables}">"Make" variable</a> substitution, the paths will be
            expanded to Windows style paths (with backslash).
          </li>
        </ul>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("cmd_bat", STRING))

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(cmd_ps) -->
        The Powershell command to run on Windows.
        <p> This attribute has higher priority than <code>cmd</code>, <code>cmd_bash</code> and
            <code>cmd_bat</code>. The command runs in the similar way as the <code>cmd</code>
            attribute, with the following differences:
        </p>
        <ul>
          <li>
            This attribute only applies on Windows.
          </li>
          <li>
            The command runs with <code>powershell.exe /c</code>.
          </li>
        </ul>
        <p> To make Powershell easier to use and less error-prone, we run the following
            commands to set up the environment before executing Powershell command in genrule.
        </p>
        <ul>
          <li>
            <code>Set-ExecutionPolicy -Scope CurrentUser RemoteSigned</code> - allow running
            unsigned scripts.
          </li>
          <li>
            <code>$errorActionPreference='Stop'</code> - In case there are multiple commands
            separated by <code>;</code>, the action exits immediately if a Powershell CmdLet fails,
            but this does <strong>NOT</strong> work for external command.
          </li>
          <li>
            <code>$PSDefaultParameterValues['*:Encoding'] = 'utf8'</code> - change the default
            encoding from utf-16 to utf-8.
          </li>
        </ul>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("cmd_ps", STRING))

        /* <!-- #BLAZE_RULE(genrule).ATTRIBUTE(output_to_bindir) -->
        <p>
          If set to True, 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 True, this option forces this <code>genrule</code> to run using the "local"
          strategy, which means no remote execution, no sandboxing, no persistent workers.
        </p>
        <p>
          This is equivalent to providing 'local' as a tag (<code>tags=["local"]</code>).
        </p>
        <!-- #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 True 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")
        .build();
  }

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