// 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.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>
        <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();
  }
}
