/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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.facebook.buck.cli;

import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.CollectingOutputReceiver;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.InstallException;
import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.TimeoutException;
import com.facebook.buck.command.Build;
import com.facebook.buck.event.LogEvent;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.DependencyGraph;
import com.facebook.buck.rules.InstallableBuildRule;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.util.AndroidManifestReader;
import com.facebook.buck.util.DefaultAndroidManifestReader;
import com.google.common.annotations.VisibleForTesting;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * Command so a user can build and install an APK.
 */
public class InstallCommand extends UninstallSupportCommandRunner<InstallCommandOptions> {

  protected InstallCommand(CommandRunnerParams params) {
    super(params);
  }

  @Override
  InstallCommandOptions createOptions(BuckConfig buckConfig) {
    return new InstallCommandOptions(buckConfig);
  }

  @Override
  int runCommandWithOptionsInternal(InstallCommandOptions options) throws IOException {
    // Make sure that only one build target is specified.
    if (options.getArguments().size() != 1) {
      getStdErr().println("Must specify exactly one android_binary() or apk_genrule() rule.");
      return 1;
    }

    // Build the specified target.
    BuildCommand buildCommand = new BuildCommand(getCommandRunnerParams());
    int exitCode = buildCommand.runCommandWithOptions(options);
    if (exitCode != 0) {
      return exitCode;
    }

    // Get the build rule that was built. Verify that it is an android_binary() rule.
    Build build = buildCommand.getBuild();
    DependencyGraph graph = build.getDependencyGraph();
    BuildRule buildRule = graph.findBuildRuleByTarget(buildCommand.getBuildTargets().get(0));
    if (!(buildRule instanceof InstallableBuildRule)) {
      console.printBuildFailure(String.format(
          "Specified rule %s must be of type android_binary() or apk_genrule() but was %s().\n",
          buildRule.getFullyQualifiedName(),
          buildRule.getType().getName()));
      return 1;
    }
    InstallableBuildRule installableBuildRule = (InstallableBuildRule)buildRule;

    // Uninstall the app first, if requested.
    if (options.shouldUninstallFirst()) {
      String packageName = tryToExtractPackageNameFromManifest(installableBuildRule);
      uninstallApk(packageName,
          options.adbOptions(),
          options.targetDeviceOptions(),
          options.uninstallOptions(),
          build.getExecutionContext());
      // Perhaps the app wasn't installed to begin with, shouldn't stop us.
    }

    if (!installApk(installableBuildRule, options, build.getExecutionContext())) {
      return 1;
    }

    // We've installed the application successfully.
    // Is either of --activity or --run present?
    if (options.shouldStartActivity()) {
      exitCode = startActivity(installableBuildRule, options.getActivityToStart(), options,
          build.getExecutionContext());
      if (exitCode != 0) {
        return exitCode;
      }
    }

    return exitCode;
  }

  private int startActivity(InstallableBuildRule androidBinaryRule, String activity,
      InstallCommandOptions options, ExecutionContext context) throws IOException {

    // Might need the package name and activities from the AndroidManifest.
    AndroidManifestReader reader = DefaultAndroidManifestReader.forPath(
        androidBinaryRule.getManifest());

    if (activity == null) {
      // Get list of activities that show up in the launcher.
      List<String> launcherActivities = reader.getLauncherActivities();

      // Sanity check.
      if (launcherActivities.isEmpty()) {
        console.printBuildFailure("No launchable activities found.");
        return 1;
      } else if (launcherActivities.size() > 1) {
        console.printBuildFailure("Default activity is ambiguous.");
        return 1;
      }

      // Construct a component for the '-n' argument of 'adb shell am start'.
      activity = reader.getPackage() + "/" + launcherActivities.get(0);
    } else if (!activity.contains("/")) {
      // If no package name was provided, assume the one in the manifest.
      activity = reader.getPackage() + "/" + activity;
    }

    final String activityToRun = activity;

    PrintStream stdOut = console.getStdOut();
    stdOut.println(String.format("Starting activity %s...", activityToRun));

    getBuckEventBus().post(StartActivityEvent.started(androidBinaryRule.getBuildTarget(),
        activityToRun));
    boolean success = adbCall(options.adbOptions(),
        options.targetDeviceOptions(),
        context,
        new AdbCallable() {
          @Override
          public boolean call(IDevice device) throws Exception {
            String err = deviceStartActivity(device, activityToRun);
            if (err != null) {
              console.printBuildFailure(err);
              return false;
            } else {
              return true;
            }
          }

          @Override
          public String toString() {
            return "start activity";
          }
        });
    getBuckEventBus().post(StartActivityEvent.finished(androidBinaryRule.getBuildTarget(),
        activityToRun,
        success));

    return success ? 0 : 1;

  }

  @VisibleForTesting
  String deviceStartActivity(IDevice device, String activityToRun) {
    try {
        ErrorParsingReceiver receiver = new ErrorParsingReceiver() {
          @Override
          protected String matchForError(String line) {
            // Parses output from shell am to determine if activity was started correctly.
            return (Pattern.matches("^([\\w_$.])*(Exception|Error|error).*$", line) ||
                line.contains("am: not found")) ? line : null;
          }
        };
        device.executeShellCommand(
            String.format("am start -n %s", activityToRun),
            receiver,
            INSTALL_TIMEOUT);
        return receiver.getErrorMessage();
    } catch (Exception e) {
      return e.toString();
    }
  }


  @Override
  String getUsageIntro() {
    return "Specify an android_binary() rule whose APK should be installed";
  }

  /**
   * Install apk on all matching devices. This functions performs device
   * filtering based on three possible arguments:
   *
   *  -e (emulator-only) - only emulators are passing the filter
   *  -d (device-only) - only real devices are passing the filter
   *  -s (serial) - only device/emulator with specific serial number are passing the filter
   *
   *  If more than one device matches the filter this function will fail unless multi-install
   *  mode is enabled (-x). This flag is used as a marker that user understands that multiple
   *  devices will be used to install the apk if needed.
   */
  @VisibleForTesting
  boolean installApk(InstallableBuildRule buildRule,
      InstallCommandOptions options,
      ExecutionContext context) {
    getBuckEventBus().post(InstallEvent.started(buildRule.getBuildTarget()));

    final File apk = new File(buildRule.getApkPath());
    final boolean installViaSd = options.shouldInstallViaSd();
    boolean success = adbCall(options.adbOptions(),
        options.targetDeviceOptions(),
        context,
        new AdbCallable() {
          @Override
          public boolean call(IDevice device) throws Exception {
            return installApkOnDevice(device, apk, installViaSd);
          }

          @Override
          public String toString() {
            return "install apk";
          }
        });
    getBuckEventBus().post(InstallEvent.finished(buildRule.getBuildTarget(), success));

    return success;
  }


  /**
   * Installs apk on specific device. Reports success or failure to console.
   */
  @VisibleForTesting
  @SuppressWarnings("PMD.PrematureDeclaration")
  boolean installApkOnDevice(IDevice device, File apk, boolean installViaSd) {
    String name;
    if (device.isEmulator()) {
      name = device.getSerialNumber() + " (" + device.getAvdName() + ")";
    } else {
      name = device.getSerialNumber();
      String model = device.getProperty("ro.product.model");
      if (model != null) {
        name += " (" + model + ")";
      }
    }

    getBuckEventBus().post(LogEvent.info("Installing apk on %s.", name));
    try {
      String reason = null;
      if (installViaSd) {
        reason = deviceInstallPackageViaSd(device, apk.getAbsolutePath());
      } else {
        reason = device.installPackage(apk.getAbsolutePath(), true);
      }
      if (reason != null) {
        console.printBuildFailure(String.format("Failed to install apk on %s: %s.", name, reason));
        return false;
      }
      return true;
    } catch (InstallException ex) {
      console.printBuildFailure(String.format("Failed to install apk on %s.", name));
      ex.printStackTrace(console.getStdErr());
      return false;
    }
  }

  /**
   * Installs apk on device, copying apk to external storage first.
   */
  private String deviceInstallPackageViaSd(IDevice device, String apk) {
    try {
      // Figure out where the SD card is mounted.
      String externalStorage = deviceGetExternalStorage(device);
      if (externalStorage == null) {
        return "Cannot get external storage location.";
      }
      String remotePackage = String.format("%s/%s.apk", externalStorage, UUID.randomUUID());
      // Copy APK to device
      device.pushFile(apk, remotePackage);
      // Install
      String reason = device.installRemotePackage(remotePackage, true);
      // Delete temporary file
      device.removeRemotePackage(remotePackage);
      return reason;
    } catch (Throwable t) {
      return String.valueOf(t.getMessage());
    }
  }

  /**
   * Retrieves external storage location (SD card) from device.
   */
  private String deviceGetExternalStorage(IDevice device) throws TimeoutException,
          AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
      CollectingOutputReceiver receiver = new CollectingOutputReceiver();
      device.executeShellCommand("echo $EXTERNAL_STORAGE", receiver, GETPROP_TIMEOUT);
      String value = receiver.getOutput().trim();
      if (value.isEmpty()) {
          return null;
      }
      return value;
  }

}
