// 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.android;

import static com.google.common.collect.MoreCollectors.onlyElement;
import static java.util.stream.Collectors.joining;

import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.analysis.Allowlist;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
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.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
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.test.ExecutionInfo;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.packages.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/** An implementation for the "android_device" rule. */
public class AndroidDevice implements RuleConfiguredTargetFactory {

  private static final Template STUB_SCRIPT =
      Template.forResource(AndroidDevice.class, "android_device_stub_template.txt");

  private static final String DEVICE_BROKER_TYPE = "WRAPPED_EMULATOR";

  static final String ALLOWLIST_NAME = "android_device";

  // Min resolution
  private static final int MIN_HORIZONTAL = 240;
  private static final int MIN_VERTICAL = 240;

  private static final int MIN_RAM = 64;
  private static final int MAX_RAM = 4096;
  private static final int MIN_VM_HEAP = 16;
  private static final int MIN_CACHE = 16;

  // http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density
  // this is a much lower pixels-per-inch then even some of the oldest phones.
  private static final int MIN_LCD_DENSITY = 30;

  private static final Predicate<Artifact> SOURCE_PROPERTIES_SELECTOR =
      (Artifact artifact) -> "source.properties".equals(artifact.getExecPath().getBaseName());

  private static final Predicate<Artifact> SOURCE_PROPERTIES_FILTER =
      Predicates.not(SOURCE_PROPERTIES_SELECTOR);

  private final AndroidSemantics androidSemantics;

  protected AndroidDevice(AndroidSemantics androidSemantics) {
    this.androidSemantics = androidSemantics;
  }

  @Override
  public ConfiguredTarget create(RuleContext ruleContext)
      throws InterruptedException, RuleErrorException, ActionConflictException {
    androidSemantics.checkForMigrationTag(ruleContext);
    checkAllowlist(ruleContext);
    Artifact executable = ruleContext.createOutputArtifact();
    Artifact metadata =
        ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_DEVICE_EMULATOR_METADATA);
    Artifact images =
        ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_DEVICE_USERDATA_IMAGES);

    NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.stableOrder();
    filesBuilder.add(executable);
    filesBuilder.add(metadata);
    filesBuilder.add(images);
    NestedSet<Artifact> filesToBuild = filesBuilder.build();

    Map<String, String> executionInfo = TargetUtils.getExecutionInfo(ruleContext.getRule());
    AndroidDeviceRuleAttributes deviceAttributes =
        new AndroidDeviceRuleAttributes(ruleContext, ImmutableMap.copyOf(executionInfo));
    if (ruleContext.hasErrors()) {
      return null;
    }

    // dependencies needed for the runfiles collector.
    Iterable<Artifact> commonDependencyArtifacts = deviceAttributes.getCommonDependencies();

    deviceAttributes.createStubScriptAction(metadata, images, executable, ruleContext);
    deviceAttributes.createBootAction(metadata, images);

    FilesToRunProvider unifiedLauncher = deviceAttributes.getUnifiedLauncher();
    Runfiles.Builder runfilesBuilder =
        new Runfiles.Builder(ruleContext.getWorkspaceName())
            .addTransitiveArtifacts(filesToBuild)
            .addArtifacts(commonDependencyArtifacts)
            .addRunfiles(ruleContext, RunfilesProvider.DEFAULT_RUNFILES);
    if (unifiedLauncher.getRunfilesSupport() != null) {
      runfilesBuilder
          .merge(unifiedLauncher.getRunfilesSupport().getRunfiles())
          .addLegacyExtraMiddleman(unifiedLauncher.getRunfilesSupport().getRunfilesMiddleman());
    } else {
      runfilesBuilder.addTransitiveArtifacts(unifiedLauncher.getFilesToRun());
    }
    Runfiles runfiles = runfilesBuilder.build();
    RunfilesSupport runfilesSupport =
        RunfilesSupport.withExecutable(ruleContext, runfiles, executable);
    NestedSet<Artifact> extraFilesToRun =
        NestedSetBuilder.create(Order.STABLE_ORDER, runfilesSupport.getRunfilesMiddleman());
    boolean dex2OatEnabled =
        ruleContext.attributes().get("pregenerate_oat_files_for_tests", Type.BOOLEAN);
    return new RuleConfiguredTargetBuilder(ruleContext)
        .setFilesToBuild(filesToBuild)
        .addProvider(RunfilesProvider.class, RunfilesProvider.simple(runfiles))
        .setRunfilesSupport(runfilesSupport, executable)
        .addFilesToRun(extraFilesToRun)
        .addNativeDeclaredProvider(new ExecutionInfo(executionInfo))
        .addNativeDeclaredProvider(new AndroidDeviceBrokerInfo(DEVICE_BROKER_TYPE))
        .addNativeDeclaredProvider(
            new AndroidDex2OatInfo(
                dex2OatEnabled,
                false /* executeDex2OatOnHost */,
                null /* deviceForPregeneratingOatFilesForTests */,
                null /* framework */,
                null /* dalvikCache */,
                null /* deviceProps */))
        .build();
  }

  private static void checkAllowlist(RuleContext ruleContext) throws RuleErrorException {
    if (!Allowlist.isAvailable(ruleContext, ALLOWLIST_NAME)) {
      ruleContext.throwWithRuleError("The android_device rule may not be used in this package");
    }
  }

  /**
   * Handles initialization phase validation of attributes, collection of dependencies and creation
   * of actions.
   */
  private static class AndroidDeviceRuleAttributes {
    private final RuleContext ruleContext;
    private final ImmutableMap<String, String> constraints;

    private final Artifact adb;
    private final Artifact emulatorArm;
    private final Artifact emulatorX86;
    private final Artifact adbStatic;
    private final ImmutableList<Artifact> emulatorX86Bios;
    private final ImmutableList<Artifact> xvfbSupportFiles;
    private final Artifact mksdcard;
    private final Artifact snapshotFs;
    private final FilesToRunProvider unifiedLauncher;
    private final Artifact androidRuntest;
    private final ImmutableList<Artifact> androidRuntestDeps;
    private final Artifact testingShbase;
    private final ImmutableList<Artifact> testingShbaseDeps;
    private final Optional<Artifact> defaultProperties;
    private final Iterable<Artifact> platformApks;
    private final Artifact sdkPath;

    private final int ram;
    private final int cache;
    private final int vmHeap;
    private final int density;
    private final int horizontalResolution;
    private final int verticalResolution;

    // These can only be null if there was an error during creation.
    private Iterable<Artifact> systemImages;
    private Artifact sourcePropertiesFile;
    private ImmutableList<Artifact> commonDependencies;

    private AndroidDeviceRuleAttributes(
        RuleContext ruleContext, ImmutableMap<String, String> executionInfo) {
      this.ruleContext = ruleContext;
      this.constraints = executionInfo;
      horizontalResolution =
          ruleContext.attributes().get("horizontal_resolution", Type.INTEGER).toIntUnchecked();
      verticalResolution =
          ruleContext.attributes().get("vertical_resolution", Type.INTEGER).toIntUnchecked();
      ram = ruleContext.attributes().get("ram", Type.INTEGER).toIntUnchecked();
      density = ruleContext.attributes().get("screen_density", Type.INTEGER).toIntUnchecked();
      cache = ruleContext.attributes().get("cache", Type.INTEGER).toIntUnchecked();
      vmHeap = ruleContext.attributes().get("vm_heap", Type.INTEGER).toIntUnchecked();

      defaultProperties =
          Optional.fromNullable(ruleContext.getPrerequisiteArtifact("default_properties"));
      adb = ruleContext.getPrerequisiteArtifact("$adb");
      emulatorArm = ruleContext.getPrerequisiteArtifact("$emulator_arm");
      emulatorX86 = ruleContext.getPrerequisiteArtifact("$emulator_x86");
      adbStatic = ruleContext.getPrerequisiteArtifact("$adb_static");
      emulatorX86Bios = ruleContext.getPrerequisiteArtifacts("$emulator_x86_bios").list();
      xvfbSupportFiles = ruleContext.getPrerequisiteArtifacts("$xvfb_support").list();
      mksdcard = ruleContext.getPrerequisiteArtifact("$mksd");
      snapshotFs = ruleContext.getPrerequisiteArtifact("$empty_snapshot_fs");
      unifiedLauncher = ruleContext.getExecutablePrerequisite("$unified_launcher");
      androidRuntestDeps = ruleContext.getPrerequisiteArtifacts("$android_runtest").list();
      androidRuntest =
          androidRuntestDeps.stream().filter(Artifact::isSourceArtifact).collect(onlyElement());
      testingShbaseDeps = ruleContext.getPrerequisiteArtifacts("$testing_shbase").list();
      testingShbase =
          testingShbaseDeps
              .stream()
              .filter(
                  (Artifact artifact) -> "googletest.sh".equals(artifact.getPath().getBaseName()))
              .collect(onlyElement());

      // may be empty
      platformApks = ruleContext.getPrerequisiteArtifacts("platform_apks").list();
      sdkPath = ruleContext.getPrerequisiteArtifact("$sdk_path");

      TransitiveInfoCollection systemImagesAndSourceProperties =
          ruleContext.getPrerequisite("system_image");
      if (ruleContext.hasErrors()) {
        return;
      }

      List<Artifact> files =
          systemImagesAndSourceProperties
              .getProvider(FileProvider.class)
              .getFilesToBuild()
              .toList();
      sourcePropertiesFile = Iterables.tryFind(files, SOURCE_PROPERTIES_SELECTOR).orNull();
      systemImages = Iterables.filter(files, SOURCE_PROPERTIES_FILTER);
      validateAttributes();
      if (sourcePropertiesFile == null) {
        ruleContext.attributeError(
            "system_image",
            "No source.properties files exist in this "
                + "filegroup ("
                + systemImagesAndSourceProperties.getLabel()
                + ")");
      }
      int numberOfSourceProperties = files.size() - Iterables.size(systemImages);
      if (numberOfSourceProperties > 1) {
        ruleContext.attributeError(
            "system_image",
            "Multiple source.properties files exist in "
                + "this filegroup ("
                + systemImagesAndSourceProperties.getLabel()
                + ")");
      }
      if (ruleContext.hasErrors()) {
        return;
      }

      commonDependencies =
          ImmutableList.<Artifact>builder()
              .add(adb)
              .add(sourcePropertiesFile)
              .addAll(systemImages)
              .add(emulatorArm)
              .add(emulatorX86)
              .add(adbStatic)
              .addAll(emulatorX86Bios)
              .addAll(xvfbSupportFiles)
              .add(mksdcard)
              .add(snapshotFs)
              .addAll(androidRuntestDeps)
              .addAll(testingShbaseDeps)
              .addAll(platformApks)
              .build();
    }

    /*
     * The stub script will find the workspace directory of its runfiles tree and then execute
     * from there.
     * The stub script gets run via blaze run, blaze-bin or as a part of a test.
     */
    private void createStubScriptAction(
        Artifact metadata, Artifact images, Artifact executable, RuleContext ruleContext) {
      List<Substitution> arguments = new ArrayList<>();
      arguments.add(Substitution.of("%workspace%", ruleContext.getWorkspaceName()));
      arguments.add(
          Substitution.of(
              "%unified_launcher%", unifiedLauncher.getExecutable().getRunfilesPathString()));
      arguments.add(Substitution.of("%adb%", adb.getRunfilesPathString()));
      arguments.add(Substitution.of("%adb_static%", adbStatic.getRunfilesPathString()));
      arguments.add(Substitution.of("%emulator_x86%", emulatorX86.getRunfilesPathString()));
      arguments.add(Substitution.of("%emulator_arm%", emulatorArm.getRunfilesPathString()));
      arguments.add(Substitution.of("%mksdcard%", mksdcard.getRunfilesPathString()));
      arguments.add(Substitution.of("%empty_snapshot_fs%", snapshotFs.getRunfilesPathString()));
      arguments.add(
          Substitution.of(
              "%system_images%",
              Streams.stream(systemImages)
                  .map(Artifact::getRunfilesPathString)
                  .collect(joining(" "))));
      arguments.add(
          Substitution.of(
              "%bios_files%",
              emulatorX86Bios.stream().map(Artifact::getRunfilesPathString).collect(joining(" "))));
      arguments.add(
          Substitution.of(
              "%source_properties_file%", sourcePropertiesFile.getRunfilesPathString()));
      arguments.add(Substitution.of("%image_input_file%", images.getRunfilesPathString()));
      arguments.add(Substitution.of("%emulator_metadata_path%", metadata.getRunfilesPathString()));
      arguments.add(Substitution.of("%android_runtest%", androidRuntest.getRunfilesPathString()));
      arguments.add(Substitution.of("%testing_shbase%", testingShbase.getRunfilesPathString()));
      arguments.add(Substitution.of("%sdk_path%", sdkPath.getRunfilesPathString()));

      ruleContext.registerAction(
          new TemplateExpansionAction(
              ruleContext.getActionOwner(), executable, STUB_SCRIPT, arguments, true));
    }

    public FilesToRunProvider getUnifiedLauncher() {
      return unifiedLauncher;
    }

    public void createBootAction(Artifact metadata, Artifact images) {
      // the boot action will run during the build so use execpath
      // strings to find all dependent artifacts (there is no nicely created runfiles
      // folder we're executing in).

      SpawnAction.Builder spawnBuilder =
          new SpawnAction.Builder()
              .addOutput(metadata)
              .addOutput(images)
              .addInputs(commonDependencies)
              .setMnemonic("AndroidDeviceBoot")
              .setProgressMessage("Creating Android image for %s", ruleContext.getLabel())
              .setExecutionInfo(constraints)
              .setExecutable(unifiedLauncher)
              // Boot resource estimation:
              // RAM: the emulator will use as much ram as has been requested in the device rule
              //   (there is a slight overhead for qemu's internals, but this is miniscule).
              // CPU: 100% - the emulator will peg a single cpu during boot because it's a very
              //   computation intensive part of the lifecycle.
              .setResources(ResourceSet.createWithRamCpu(ram, 1))
              .addExecutableArguments(
                  "--action=boot",
                  "--density=" + density,
                  "--memory=" + ram,
                  "--cache=" + cache,
                  "--vm_size=" + vmHeap,
                  "--generate_output_dir="
                      + images.getExecPath().getParentDirectory().getPathString(),
                  "--skin=" + getScreenSize(),
                  "--source_properties_file=" + sourcePropertiesFile.getExecPathString(),
                  "--system_images=" + Artifact.joinExecPaths(" ", systemImages),
                  "--flag_configured_android_tools",
                  "--adb=" + adb.getExecPathString(),
                  "--emulator_x86=" + emulatorX86.getExecPathString(),
                  "--emulator_arm=" + emulatorArm.getExecPathString(),
                  "--adb_static=" + adbStatic.getExecPathString(),
                  "--mksdcard=" + mksdcard.getExecPathString(),
                  "--empty_snapshot_fs=" + snapshotFs.getExecPathString(),
                  "--bios_files=" + Artifact.joinExecPaths(",", emulatorX86Bios),
                  "--nocopy_system_images",
                  "--single_image_file",
                  "--android_sdk_path=" + sdkPath.getExecPathString(),
                  "--platform_apks=" + Artifact.joinExecPaths(",", platformApks));

      CustomCommandLine.Builder commandLine = CustomCommandLine.builder();
      if (defaultProperties.isPresent()) {
        spawnBuilder.addInput(defaultProperties.get());
        commandLine.addPrefixedExecPath("--default_properties_file=", defaultProperties.get());
      }
      spawnBuilder.addCommandLine(commandLine.build());
      ruleContext.registerAction(spawnBuilder.build(ruleContext));
    }

    public ImmutableList<Artifact> getCommonDependencies() {
      return commonDependencies;
    }

    private void validateAttributes() {
      if (horizontalResolution < MIN_HORIZONTAL) {
        ruleContext.attributeError(
            "horizontal_resolution", "horizontal must be at least: " + MIN_HORIZONTAL);
      }
      if (verticalResolution < MIN_VERTICAL) {
        ruleContext.attributeError(
            "vertical_resolution", "vertical must be at least: " + MIN_VERTICAL);
      }
      if (ram < MIN_RAM) {
        ruleContext.attributeError("ram", "ram must be at least: " + MIN_RAM);
      }
      if (ram > MAX_RAM) {
        ruleContext.attributeError("ram", "ram cannot be greater than: " + MAX_RAM);
      }
      if (density < MIN_LCD_DENSITY) {
        ruleContext.attributeError(
            "screen_density", "density must be at least: " + MIN_LCD_DENSITY);
      }
      if (cache < MIN_CACHE) {
        ruleContext.attributeError("cache", "cache must be at least: " + MIN_CACHE);
      }
      if (vmHeap < MIN_VM_HEAP) {
        ruleContext.attributeError("vm_heap", "vm heap must be at least: " + MIN_VM_HEAP);
      }
    }

    private String getScreenSize() {
      return horizontalResolution + "x" + verticalResolution;
    }
  }
}
