// Copyright 2014 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.bazel.rules.python;

import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.BuildType.TRISTATE;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import static com.google.devtools.build.lib.syntax.Type.STRING;
import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;

import com.google.common.collect.ImmutableList;
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.bazel.rules.cpp.BazelCppRuleClasses.CcToolchainRequiringRule;
import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault;
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.SkylarkProviderIdentifier;
import com.google.devtools.build.lib.packages.TriState;
import com.google.devtools.build.lib.rules.python.PyCommon;
import com.google.devtools.build.lib.rules.python.PyInfo;
import com.google.devtools.build.lib.rules.python.PyRuleClasses;
import com.google.devtools.build.lib.rules.python.PyStructUtils;
import com.google.devtools.build.lib.rules.python.PythonVersion;
import com.google.devtools.build.lib.util.FileType;

/**
 * Bazel-specific rule definitions for Python rules.
 */
public final class BazelPyRuleClasses {
  public static final FileType PYTHON_SOURCE = FileType.of(".py");

  public static final LabelLateBoundDefault<?> PY_INTERPRETER =
      LabelLateBoundDefault.fromTargetConfiguration(
          BazelPythonConfiguration.class,
          null,
          (rule, attributes, bazelPythonConfig) -> bazelPythonConfig.getPythonTop());

  /**
   * Base class for Python rule definitions.
   */
  public static final class PyBaseRule implements RuleDefinition {
    @Override
    public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
      return builder
          /* <!-- #BLAZE_RULE($base_py).ATTRIBUTE(deps) -->
          The list of other libraries to be linked in to the binary target.
          See general comments about <code>deps</code> at
          <a href="${link common-definitions#common-attributes}">
          Attributes common to all build rules</a>.
          These are generally
          <a href="${link py_library}"><code>py_library</code></a> rules.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .override(
              builder
                  .copy("deps")
                  .mandatoryProvidersList(
                      ImmutableList.of(
                          // Legacy provider.
                          // TODO(#7010): Remove this legacy set.
                          ImmutableList.of(
                              SkylarkProviderIdentifier.forLegacy(PyStructUtils.PROVIDER_NAME)),
                          // Modern provider.
                          ImmutableList.of(PyInfo.PROVIDER.id())))
                  .allowedFileTypes())
          /* <!-- #BLAZE_RULE($base_py).ATTRIBUTE(imports) -->
          List of import directories to be added to the <code>PYTHONPATH</code>.
          <p>
          Subject to <a href="${link make-variables}">"Make variable"</a> substitution. These import
          directories will be added for this rule and all rules that depend on it (note: not the
          rules this rule depends on. Each directory will be added to <code>PYTHONPATH</code> by
          <a href="${link py_binary}"><code>py_binary</code></a> rules that depend on this rule.
          </p>
          <p>
          Absolute paths (paths that start with <code>/</code>) and paths that references a path
          above the execution root are not allowed and will result in an error.
          </p>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("imports", STRING_LIST).value(ImmutableList.<String>of()))
          /* <!-- #BLAZE_RULE($base_py).ATTRIBUTE(srcs_version) -->
          This attribute declares the target's <code>srcs</code> to be compatible with either Python
          2, Python 3, or both. To actually set the Python runtime version, use the
          <a href="${link py_binary.python_version}"><code>python_version</code></a> attribute of an
          executable Python rule (<code>py_binary</code> or <code>py_test</code>).

          <p>Allowed values are: <code>"PY2AND3"</code>, <code>"PY2"</code>, and <code>"PY3"</code>.
          The values <code>"PY2ONLY"</code> and <code>"PY3ONLY"</code> are also allowed for historic
          reasons, but they are essentially the same as <code>"PY2"</code> and <code>"PY3"</code>
          and should be avoided.

          <p>Under the old semantics
          (<code>--incompatible_allow_python_version_transitions=false</code>), it is an error to
          build any Python target for a version disallowed by its <code>srcs_version</code>
          attribute. Under the new semantics
          (<code>--incompatible_allow_python_version_transitions=true</code>), this check is
          deferred to the executable rule: You can build a <code>srcs_version = "PY3"</code>
          <code>py_library</code> target for Python 2, but you cannot actually depend on it via
          <code>deps</code> from a Python 3 <code>py_binary</code>.

          <p>To get diagnostic information about which dependencies introduce version requirements,
          you can run the <code>find_requirements</code> aspect on your target:
          <pre>
          bazel build &lt;your target&gt; \
              --aspects=@bazel_tools//tools/python:srcs_version.bzl%find_requirements \
              --output_groups=pyversioninfo
          </pre>
          This will build a file with the suffix <code>-pyversioninfo.txt</code> giving information
          about why your target requires one Python version or another. Note that it works even if
          the given target failed to build due to a version conflict.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("srcs_version", STRING)
                  .value(PythonVersion.DEFAULT_SRCS_VALUE.toString())
                  .allowedValues(new AllowedValueSet(PythonVersion.SRCS_STRINGS)))
          // TODO(brandjon): Consider adding to py_interpreter a .mandatoryNativeProviders() of
          // BazelPyRuntimeProvider. (Add a test case to PythonConfigurationTest for violations
          // of this requirement.)
          .add(attr(":py_interpreter", LABEL).value(PY_INTERPRETER))
          // do not depend on lib2to3:2to3 rule, because it creates circular dependencies
          // 2to3 is itself written in Python and depends on many libraries.
          .add(
              attr("$python2to3", LABEL)
                  .cfg(HostTransition.INSTANCE)
                  .exec()
                  .value(env.getToolsLabel("//tools/python:2to3")))
          .setPreferredDependencyPredicate(PyRuleClasses.PYTHON_SOURCE)
          .build();
    }

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

  /**
   * Base class for Python rule definitions that produce binaries.
   */
  public static final class PyBinaryBaseRule implements RuleDefinition {
    @Override
    public RuleClass build(RuleClass.Builder builder, final RuleDefinitionEnvironment env) {
      return builder
          /* <!-- #BLAZE_RULE($base_py_binary).ATTRIBUTE(main) -->
          The name of the source file that is the main entry point of the application.
          This file must also be listed in <code>srcs</code>. If left unspecified,
          <code>name</code> is used instead (see above). If <code>name</code> does not
          match any filename in <code>srcs</code>, <code>main</code> must be specified.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("main", LABEL).allowedFileTypes(PYTHON_SOURCE))
          /* <!-- #BLAZE_RULE($base_py_binary).ATTRIBUTE(default_python_version) -->
          A deprecated alias for <code>python_version</code>; use that instead. This attribute is
          disabled under <code>--incompatible_remove_old_python_version_api</code>. For migration
          purposes, if <code>python_version</code> is given then the value of
          <code>default_python_version</code> is ignored.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr(PyCommon.DEFAULT_PYTHON_VERSION_ATTRIBUTE, STRING)
                  .value(PythonVersion._INTERNAL_SENTINEL.toString())
                  .allowedValues(PyRuleClasses.TARGET_PYTHON_ATTR_VALUE_SET)
                  .nonconfigurable(
                      "read by PyRuleClasses.PYTHON_VERSION_TRANSITION, which doesn't have access"
                          + " to the configuration"))
          /* <!-- #BLAZE_RULE($base_py_binary).ATTRIBUTE(python_version) -->
          Whether to build this target (and its transitive <code>deps</code>) for Python 2 or Python
          3. Valid values are <code>"PY2"</code> (the default) and <code>"PY3"</code>.

          <p>Under the old semantics
          (<code>--incompatible_allow_python_version_transitions=false</code>), the Python version
          generally cannot be changed once set. This means that the <code>--python_version</code>
          flag overrides this attribute, and other Python binaries in the <code>data</code> deps of
          this target are forced to use the same version as this target.

          <p>Under the new semantics
          (<code>--incompatible_allow_python_version_transitions=true</code>), the Python version
          is always set (possibly by default) to whatever version is specified by this attribute,
          regardless of the version specified on the command line or by other targets that depend on
          this one.

          <p>If you want to <code>select()</code> on the current Python version, you can inspect the
          value of <code>@bazel_tools//tools/python:python_version</code>. See
          <a href="https://github.com/bazelbuild/bazel/blob/4b74ea9a3f81b7ed30562f1689827b5488884c86/tools/python/BUILD#L33">here</a>
          for more information.

          <p><b>Bug warning:</b> This attribute sets the version for which Bazel builds your target,
          but due to <a href="https://github.com/bazelbuild/bazel/issues/4815">#4815</a>, the
          resulting stub script may still invoke the wrong interpreter version at runtime. See
          <a href="https://github.com/bazelbuild/bazel/issues/4815#issuecomment-460777113">this
          workaround</a>, which involves defining a <code>py_runtime</code> target that points to
          either Python version as needed, and activating this <code>py_runtime</code> by setting
          <code>--python_top</code>.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr(PyCommon.PYTHON_VERSION_ATTRIBUTE, STRING)
                  .value(PythonVersion._INTERNAL_SENTINEL.toString())
                  .allowedValues(PyRuleClasses.TARGET_PYTHON_ATTR_VALUE_SET)
                  .nonconfigurable(
                      "read by PyRuleClasses.PYTHON_VERSION_TRANSITION, which doesn't have access"
                          + " to the configuration"))
          /* <!-- #BLAZE_RULE($base_py_binary).ATTRIBUTE(srcs) -->
          The list of source (<code>.py</code>) files that are processed to create the target.
          This includes all your checked-in code and any generated source files. Library targets
          belong in <code>deps</code> instead, while other binary files needed at runtime belong in
          <code>data</code>.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("srcs", LABEL_LIST)
                  .mandatory()
                  .allowedFileTypes(PYTHON_SOURCE)
                  .direct_compile_time_input())
          /* <!-- #BLAZE_RULE($base_py_binary).ATTRIBUTE(legacy_create_init) -->
          Whether to implicitly create empty __init__.py files in the runfiles tree.
          These are created in every directory containing Python source code or
          shared libraries, and every parent directory of those directories, excluding the repo root
          directory. The default is true for backward compatibility. If false, the user is
          responsible for creating (possibly empty) __init__.py files and adding them to the
          <code>srcs</code> of Python targets as required.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("legacy_create_init", BOOLEAN).value(true))
          /* <!-- #BLAZE_RULE($base_py_binary).ATTRIBUTE(stamp) -->
          Enable link stamping.
          Whether to encode build information into the binary. Possible values:
          <ul>
            <li><code>stamp = 1</code>: Stamp the build information into the
              binary. Stamped binaries are only rebuilt when their dependencies
              change. Use this if there are tests that depend on the build
              information.</li>
            <li><code>stamp = 0</code>: Always replace build information by constant
              values. This gives good build result caching.</li>
            <li><code>stamp = -1</code>: Embedding of build information is controlled
              by the <a href="../user-manual.html#flag--stamp">--[no]stamp</a> Blaze
              flag.</li>
          </ul>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("stamp", TRISTATE).value(TriState.AUTO))
          .build();
    }

    @Override
    public Metadata getMetadata() {
      return RuleDefinition.Metadata.builder()
          .name("$base_py_binary")
          .type(RuleClassType.ABSTRACT)
          .ancestors(PyBaseRule.class, CcToolchainRequiringRule.class)
          .build();
    }
  }
}
