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