// 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;
import javax.annotation.Nullable;

/** 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
  @Nullable
  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;
    }
  }
}
