// 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(exec_tools) -->
        <b>Deprecated. Use <a href="#genrule.tools"><code>tools</code></a> instead.</b>

        <p>
          There was a period of time when <code>exec_tools</code> and <code>tools</code> behaved
          differently, but they are now equivalent and the Blaze team will be migrating all uses of
          <code>exec_tools</code> to <code>tools</code>.
        </p>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(
            attr("exec_tools", LABEL_LIST)
                .cfg(ExecutionTransitionFactory.createFactory())
                .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();
  }
}
