// 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 java.nio.charset.StandardCharsets.ISO_8859_1;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Streams;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ParamFileInfo;
import com.google.devtools.build.lib.actions.ParameterFile;
import com.google.devtools.build.lib.analysis.AnalysisUtils;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.RunfilesSupport;
import com.google.devtools.build.lib.analysis.ShToolchain;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.LauncherFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.LauncherFileWriteAction.LaunchInfo;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.actions.Substitution;
import com.google.devtools.build.lib.analysis.actions.Template;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector.InstrumentationSpec;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.cpp.CcInfo;
import com.google.devtools.build.lib.rules.python.PyCcLinkParamsProvider;
import com.google.devtools.build.lib.rules.python.PyCommon;
import com.google.devtools.build.lib.rules.python.PyRuntimeInfo;
import com.google.devtools.build.lib.rules.python.PythonConfiguration;
import com.google.devtools.build.lib.rules.python.PythonSemantics;
import com.google.devtools.build.lib.rules.python.PythonVersion;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;

/** Functionality specific to the Python rules in Bazel. */
public class BazelPythonSemantics implements PythonSemantics {

  private static final Template STUB_TEMPLATE =
      Template.forResource(BazelPythonSemantics.class, "python_stub_template.txt");
  public static final InstrumentationSpec PYTHON_COLLECTION_SPEC = new InstrumentationSpec(
      FileTypeSet.of(BazelPyRuleClasses.PYTHON_SOURCE),
      "srcs", "deps", "data");

  public static final PathFragment ZIP_RUNFILES_DIRECTORY_NAME = PathFragment.create("runfiles");

  @Override
  public String getSrcsVersionDocURL() {
    // TODO(#8996): Update URL to point to rules_python's docs instead of the Bazel site.
    return "https://docs.bazel.build/versions/master/be/python.html#py_binary.srcs_version";
  }

  @Override
  public void validate(RuleContext ruleContext, PyCommon common) {
  }

  @Override
  public void collectRunfilesForBinary(
      RuleContext ruleContext, Runfiles.Builder builder, PyCommon common, CcInfo ccInfo) {
    addRuntime(ruleContext, common, builder);
  }

  @Override
  public void collectDefaultRunfilesForBinary(
      RuleContext ruleContext, PyCommon common, Runfiles.Builder builder) {
    addRuntime(ruleContext, common, builder);
  }

  @Override
  public void collectDefaultRunfiles(RuleContext ruleContext, Runfiles.Builder builder) {
    builder.addRunfiles(ruleContext, RunfilesProvider.DEFAULT_RUNFILES);
  }

  @Override
  public InstrumentationSpec getCoverageInstrumentationSpec() {
    return PYTHON_COLLECTION_SPEC;
  }

  @Override
  public Collection<Artifact> precompiledPythonFiles(
      RuleContext ruleContext, Collection<Artifact> sources, PyCommon common) {
    return ImmutableList.copyOf(sources);
  }

  @Override
  public List<String> getImports(RuleContext ruleContext) {
    List<String> result = new ArrayList<>();
    PathFragment packageFragment = ruleContext.getLabel().getPackageIdentifier().getRunfilesPath();
    // Python scripts start with x.runfiles/ as the module space, so everything must be manually
    // adjusted to be relative to the workspace name.
    packageFragment = PathFragment.create(ruleContext.getWorkspaceName())
        .getRelative(packageFragment);
    for (String importsAttr : ruleContext.getExpander().list("imports")) {
      if (importsAttr.startsWith("/")) {
        ruleContext.attributeWarning("imports",
            "ignoring invalid absolute path '" + importsAttr + "'");
        continue;
      }
      PathFragment importsPath = packageFragment.getRelative(importsAttr);
      if (importsPath.containsUplevelReferences()) {
        ruleContext.attributeError("imports",
            "Path " + importsAttr + " references a path above the execution root");
      }
      result.add(importsPath.getPathString());
    }
    return result;
  }

  private static String boolToLiteral(boolean value) {
    return value ? "True" : "False";
  }

  private static String versionToLiteral(PythonVersion version) {
    Preconditions.checkArgument(version.isTargetValue());
    return version == PythonVersion.PY3 ? "\"3\"" : "\"2\"";
  }

  private static void createStubFile(
      RuleContext ruleContext, Artifact stubOutput, PyCommon common, boolean isForZipFile) {
    PythonConfiguration config = ruleContext.getFragment(PythonConfiguration.class);
    BazelPythonConfiguration bazelConfig = ruleContext.getFragment(BazelPythonConfiguration.class);

    // The second-stage Python interpreter, which may be a system absolute path or a runfiles
    // workspace-relative path. On Windows this is also passed to the launcher to use for the
    // first-stage.
    String pythonBinary = getPythonBinary(ruleContext, common, bazelConfig);

    // Version information for host config diagnostic warning.
    PythonVersion attrVersion = PyCommon.readPythonVersionFromAttribute(ruleContext.attributes());
    boolean attrVersionSpecifiedExplicitly = attrVersion != null;
    if (!attrVersionSpecifiedExplicitly) {
      attrVersion = config.getDefaultPythonVersion();
    }

    // Create the stub file.
    ruleContext.registerAction(
        new TemplateExpansionAction(
            ruleContext.getActionOwner(),
            stubOutput,
            STUB_TEMPLATE,
            ImmutableList.of(
                Substitution.of(
                    "%main%", common.determineMainExecutableSource(/*withWorkspaceName=*/ true)),
                Substitution.of("%python_binary%", pythonBinary),
                Substitution.of("%imports%", Joiner.on(":").join(common.getImports().toList())),
                Substitution.of("%workspace_name%", ruleContext.getWorkspaceName()),
                Substitution.of("%is_zipfile%", boolToLiteral(isForZipFile)),
                Substitution.of(
                    "%import_all%", boolToLiteral(bazelConfig.getImportAllRepositories())),
                Substitution.of(
                    "%enable_host_version_warning%",
                    boolToLiteral(common.shouldWarnAboutHostVersionUponFailure())),
                Substitution.of(
                    "%target%", ruleContext.getRule().getLabel().getDefaultCanonicalForm()),
                Substitution.of(
                    "%python_version_from_config%", versionToLiteral(common.getVersion())),
                Substitution.of("%python_version_from_attr%", versionToLiteral(attrVersion)),
                Substitution.of(
                    "%python_version_specified_explicitly%",
                    boolToLiteral(attrVersionSpecifiedExplicitly))),
            true));
  }

  @Override
  public void createExecutable(
      RuleContext ruleContext, PyCommon common, CcInfo ccInfo, Runfiles.Builder runfilesBuilder)
      throws InterruptedException {
    PythonConfiguration config = ruleContext.getFragment(PythonConfiguration.class);
    BazelPythonConfiguration bazelConfig = ruleContext.getFragment(BazelPythonConfiguration.class);
    boolean buildPythonZip = config.buildPythonZip();

    /*
     * Python executable targets are launched in two stages. The first stage is the stub script that
     * locates (and possibly extracts) the runfiles tree, sets up environment variables, and passes
     * control to the second stage. The second stage is payload user code, i.e. the main Python
     * file.
     *
     * When a zip file is built (--build_python_zip), the stub script becomes the __main__.py of the
     * resulting zip, so that it runs when a Python interpreter executes the zip file. The stub
     * logic will extract the zip's runfiles into a temporary directory.
     *
     * The stub script has a shebang pointing to a first-stage Python interpreter (as of this
     * writing "#!/usr/bin/env python"). When a zip file is built on unix, this shebang is also
     * prepended to the final zip artifact. On Windows shebangs are ignored, and the launcher
     * runs the first stage with an interpreter whose path is passed in as LaunchInfo.
     */

    // The initial entry point, which is the launcher on Windows, or the stub or zip file on Unix.
    Artifact executable = common.getExecutable();

    // The second-stage Python interpreter, which may be a system absolute path or a runfiles
    // workspace-relative path. On Windows this is also passed to the launcher to use for the
    // first-stage.
    String pythonBinary = getPythonBinary(ruleContext, common, bazelConfig);

    // Create the stub file used for a non-zipfile executable. If --build_python_zip is true this is
    // never used so we skip it.
    if (!buildPythonZip) {
      Artifact stubOutput =
          OS.getCurrent() == OS.WINDOWS
              ? common.getPythonStubArtifactForWindows(executable)
              : executable;
      createStubFile(ruleContext, stubOutput, common, /* isForZipFile= */ false);
    }

    // Create the zip file if requested. On unix, copy it from the intermediate artifact to the
    // final executable while prepending the shebang.
    if (buildPythonZip) {
      Artifact zipFile = common.getPythonZipArtifact(executable);

      if (OS.getCurrent() != OS.WINDOWS) {
        PathFragment shExecutable = ShToolchain.getPathOrError(ruleContext);
        // TODO(#8685): Remove this special-case handling as part of making the proper shebang a
        // property of the Python toolchain configuration.
        String pythonExecutableName = OS.getCurrent() == OS.OPENBSD ? "python3" : "python";
        ruleContext.registerAction(
            new SpawnAction.Builder()
                .addInput(zipFile)
                .addOutput(executable)
                .setShellCommand(
                    shExecutable,
                    "echo '#!/usr/bin/env "
                        + pythonExecutableName
                        + "' | cat - "
                        + zipFile.getExecPathString()
                        + " > "
                        + executable.getExecPathString())
                .useDefaultShellEnvironment()
                .setMnemonic("BuildBinary")
                .build(ruleContext));
      }
    }

    // On Windows, create the launcher.
    if (OS.getCurrent() == OS.WINDOWS) {
      createWindowsExeLauncher(
          ruleContext,
          // In the case where the second-stage interpreter is in runfiles, the launcher is passed
          // a workspace-relative path that it combines with its own CWD to produce the full path to
          // the real interpreter executable. (It can't use a path to the runfiles since they aren't
          // yet extracted from the zip, assuming buildPythonZip is set.)
          //
          // TODO(#7947): Fix how this path is constructed for the case of a runfile interpreter in
          // a remote repo -- probably need to pass an absolute path to the launcher instead of a
          // workspace-relative one. Also ensure this is ok for remote execution, and if not, maybe
          // change the launcher to use a separate system-installed first-stage interpreter like on
          // unix. See also https://github.com/bazelbuild/bazel/issues/7947#issuecomment-491385802.
          pythonBinary,
          executable,
          /*useZipFile=*/ buildPythonZip);
    }
  }

  /** Registers an action to create a Windows Python launcher at {@code pythonLauncher}. */
  private static void createWindowsExeLauncher(
      RuleContext ruleContext, String pythonBinary, Artifact pythonLauncher, boolean useZipFile)
      throws InterruptedException {
    LaunchInfo launchInfo =
        LaunchInfo.builder()
            .addKeyValuePair("binary_type", "Python")
            .addKeyValuePair("workspace_name", ruleContext.getWorkspaceName())
            .addKeyValuePair(
                "symlink_runfiles_enabled",
                ruleContext.getConfiguration().runfilesEnabled() ? "1" : "0")
            .addKeyValuePair("python_bin_path", pythonBinary)
            .addKeyValuePair("use_zip_file", useZipFile ? "1" : "0")
            .build();
    LauncherFileWriteAction.createAndRegister(ruleContext, pythonLauncher, launchInfo);
  }

  @Override
  public void postInitExecutable(
      RuleContext ruleContext,
      RunfilesSupport runfilesSupport,
      PyCommon common,
      RuleConfiguredTargetBuilder builder) {
    FilesToRunProvider zipper = ruleContext.getExecutablePrerequisite("$zipper", Mode.HOST);
    Artifact executable = common.getExecutable();
    Artifact zipFile = common.getPythonZipArtifact(executable);

    if (!ruleContext.hasErrors()) {
      // Create the stub file that's needed by the python zip file.
      Artifact stubFileForZipFile = common.getPythonIntermediateStubArtifact(executable);
      createStubFile(ruleContext, stubFileForZipFile, common, /* isForZipFile= */ true);

      createPythonZipAction(
          ruleContext, executable, zipFile, stubFileForZipFile, zipper, runfilesSupport);
    }
    builder.addOutputGroup("python_zip_file", zipFile);
  }

  private static boolean isUnderWorkspace(PathFragment path) {
    return !path.startsWith(LabelConstants.EXTERNAL_PATH_PREFIX);
  }

  private static String getZipRunfilesPath(PathFragment path, PathFragment workspaceName) {
    String zipRunfilesPath;
    if (isUnderWorkspace(path)) {
      // If the file is under workspace, add workspace name as prefix
      zipRunfilesPath = workspaceName.getRelative(path).toString();
    } else {
      // If the file is in external package, strip "external"
      zipRunfilesPath = path.relativeTo(LabelConstants.EXTERNAL_PATH_PREFIX).toString();
    }
    // We put the whole runfiles tree under the ZIP_RUNFILES_DIRECTORY_NAME directory, by doing this
    // , we avoid the conflict between default workspace name "__main__" and __main__.py file.
    // Note: This name has to be the same with the one in python_stub_template.txt.
    return ZIP_RUNFILES_DIRECTORY_NAME.getRelative(zipRunfilesPath).toString();
  }

  private static String getZipRunfilesPath(String path, PathFragment workspaceName) {
    return getZipRunfilesPath(PathFragment.create(path), workspaceName);
  }

  private static void createPythonZipAction(
      RuleContext ruleContext,
      Artifact executable,
      Artifact zipFile,
      Artifact stubFile,
      FilesToRunProvider zipper,
      RunfilesSupport runfilesSupport) {

    NestedSetBuilder<Artifact> inputsBuilder = NestedSetBuilder.stableOrder();
    PathFragment workspaceName = runfilesSupport.getWorkspaceName();
    CustomCommandLine.Builder argv = new CustomCommandLine.Builder();
    inputsBuilder.add(stubFile);
    argv.addPrefixedExecPath("__main__.py=", stubFile);

    // Creating __init__.py files under each directory
    argv.add("__init__.py=");
    argv.addDynamicString(getZipRunfilesPath("__init__.py", workspaceName) + "=");
    for (String path : runfilesSupport.getRunfiles().getEmptyFilenames().toList()) {
      argv.addDynamicString(getZipRunfilesPath(path, workspaceName) + "=");
    }

    // Read each runfile from execute path, add them into zip file at the right runfiles path.
    // Filter the executable file, cause we are building it.
    for (Artifact artifact : runfilesSupport.getRunfilesArtifacts().toList()) {
      if (!artifact.equals(executable) && !artifact.equals(zipFile)) {
        argv.addDynamicString(
            getZipRunfilesPath(artifact.getRunfilesPath(), workspaceName)
                + "="
                + artifact.getExecPathString());
        inputsBuilder.add(artifact);
      }
    }

    ruleContext.registerAction(
        new SpawnAction.Builder()
            .addTransitiveInputs(inputsBuilder.build())
            .addOutput(zipFile)
            .setExecutable(zipper)
            .useDefaultShellEnvironment()
            .addCommandLine(CustomCommandLine.builder().add("cC").addExecPath(zipFile).build())
            // zipper can only consume file list options from param file not other options,
            // so write file list in the param file.
            .addCommandLine(
                argv.build(),
                ParamFileInfo.builder(ParameterFile.ParameterFileType.UNQUOTED)
                    .setCharset(ISO_8859_1)
                    .setUseAlways(true)
                    .build())
            .setMnemonic("PythonZipper")
            .build(ruleContext));
  }

  /**
   * Returns the Python runtime to use, either from the toolchain or the legacy flag-based
   * mechanism.
   *
   * <p>Can only be called for an executable Python rule.
   *
   * <p>Returns {@code null} if there's a problem retrieving the runtime.
   */
  @Nullable
  private static PyRuntimeInfo getRuntime(RuleContext ruleContext, PyCommon common) {
    return common.shouldGetRuntimeFromToolchain()
        ? common.getRuntimeFromToolchain()
        : ruleContext.getPrerequisite(":py_interpreter", Mode.TARGET, PyRuntimeInfo.PROVIDER);
  }

  private static void addRuntime(
      RuleContext ruleContext, PyCommon common, Runfiles.Builder builder) {
    PyRuntimeInfo provider = getRuntime(ruleContext, common);
    if (provider != null && provider.isInBuild()) {
      builder.addArtifact(provider.getInterpreter());
      // WARNING: we are adding the all Python runtime files here,
      // and it would fail if the filenames of them contain spaces.
      // Currently, we need to exclude them in py_runtime rules.
      // Possible files in Python runtime which contain spaces in filenames:
      // - https://github.com/pypa/setuptools/blob/master/setuptools/script%20(dev).tmpl
      // - https://github.com/pypa/setuptools/blob/master/setuptools/command/launcher%20manifest.xml
      builder.addTransitiveArtifacts(provider.getFiles());
    }
  }

  private static String getPythonBinary(
      RuleContext ruleContext, PyCommon common, BazelPythonConfiguration bazelConfig) {
    String pythonBinary;
    PyRuntimeInfo provider = getRuntime(ruleContext, common);
    if (provider != null) {
      // make use of py_runtime defined by --python_top
      if (!provider.isInBuild()) {
        // absolute Python path in py_runtime
        pythonBinary = provider.getInterpreterPath().getPathString();
      } else {
        // checked in Python interpreter in py_runtime
        PathFragment workspaceName =
            PathFragment.create(ruleContext.getRule().getPackage().getWorkspaceName());
        pythonBinary =
            workspaceName.getRelative(provider.getInterpreter().getRunfilesPath()).getPathString();
      }
    } else  {
      // make use of the Python interpreter in an absolute path
      pythonBinary = bazelConfig.getPythonPath();
    }

    return pythonBinary;
  }

  @Override
  public CcInfo buildCcInfoProvider(Iterable<? extends TransitiveInfoCollection> deps) {
    ImmutableList<CcInfo> ccInfos =
        ImmutableList.<CcInfo>builder()
            .addAll(AnalysisUtils.getProviders(deps, CcInfo.PROVIDER))
            .addAll(
                Streams.stream(AnalysisUtils.getProviders(deps, PyCcLinkParamsProvider.PROVIDER))
                    .map(PyCcLinkParamsProvider::getCcInfo)
                    .collect(ImmutableList.toImmutableList()))
            .build();

    // TODO(plf): return empty CcInfo.
    return CcInfo.merge(ccInfos);
  }
}
