/*
 * Copyright 2016 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.idea.blaze.android.run.test;

import com.android.ddmlib.IDevice;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
import com.android.tools.idea.run.ApkProvisionException;
import com.android.tools.idea.run.ApplicationIdProvider;
import com.android.tools.idea.run.ConsolePrinter;
import com.android.tools.idea.run.tasks.LaunchTask;
import com.android.tools.idea.run.util.LaunchStatus;
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestListener;
import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.jetbrains.android.dom.manifest.Manifest;

final class StockAndroidTestLaunchTask implements LaunchTask {
  private static final Logger LOG = Logger.getInstance(StockAndroidTestLaunchTask.class);

  private final BlazeAndroidTestRunConfigurationState configState;
  private final String instrumentationTestRunner;
  private final String testApplicationId;
  private final boolean waitForDebugger;

  private StockAndroidTestLaunchTask(
      BlazeAndroidTestRunConfigurationState configState,
      String runner,
      String testPackage,
      boolean waitForDebugger) {
    this.configState = configState;
    this.instrumentationTestRunner = runner;
    this.waitForDebugger = waitForDebugger;
    this.testApplicationId = testPackage;
  }

  public static LaunchTask getStockTestLaunchTask(
      BlazeAndroidTestRunConfigurationState configState,
      ApplicationIdProvider applicationIdProvider,
      boolean waitForDebugger,
      BlazeAndroidDeployInfo deployInfo,
      LaunchStatus launchStatus) {
    String testPackage;
    try {
      testPackage = applicationIdProvider.getTestPackageName();
      if (testPackage == null) {
        launchStatus.terminateLaunch("Unable to determine test package name");
        return null;
      }
    } catch (ApkProvisionException e) {
      launchStatus.terminateLaunch("Unable to determine test package name");
      return null;
    }

    List<String> availableRunners = getRunnersFromManifest(deployInfo);
    if (availableRunners.isEmpty()) {
      launchStatus.terminateLaunch(
          String.format(
              "No instrumentation test runner is defined in the manifest.\n"
                  + "At least one instrumentation tag must be defined for the\n"
                  + "\"%1$s\" package in the AndroidManifest.xml, e.g.:\n"
                  + "\n"
                  + "<manifest\n"
                  + "    package=\"%1$s\"\n"
                  + "    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n"
                  + "\n"
                  + "    <instrumentation\n"
                  + "        android:name=\"android.support.test.runner.AndroidJUnitRunner\"\n"
                  + "        android:targetPackage=\"%1$s\">\n"
                  + "    </instrumentation>\n"
                  + "\n"
                  + "</manifest>",
              testPackage));
      // Note: Gradle users will never see the above message, so don't mention Gradle here.
      // Even if no runners are defined in build.gradle, Gradle will add a default to the manifest.
      return null;
    }
    String runner = configState.getInstrumentationRunnerClass();
    if (!StringUtil.isEmpty(runner)) {
      if (!availableRunners.contains(runner)) {
        launchStatus.terminateLaunch(
            String.format(
                "Instrumentation test runner \"%2$s\"\n"
                    + "is not defined for the \"%1$s\" package in the manifest.\n"
                    + "Clear the 'Specific instrumentation runner' field in your configuration\n"
                    + "to default to \"%3$s\",\n"
                    + "or add the runner to your AndroidManifest.xml:\n"
                    + "\n"
                    + "<manifest\n"
                    + "    package=\"%1$s\"\n"
                    + "    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n"
                    + "\n"
                    + "    <instrumentation\n"
                    + "        android:name=\"%2$s\"\n"
                    + "        android:targetPackage=\"%1$s\">\n"
                    + "    </instrumentation>\n"
                    + "\n"
                    + "</manifest>",
                testPackage, runner, availableRunners.get(0)));
        return null;
      }
    } else {
      // Default to the first available runner.
      runner = availableRunners.get(0);
    }

    return new StockAndroidTestLaunchTask(configState, runner, testPackage, waitForDebugger);
  }

  private static ImmutableList<String> getRunnersFromManifest(
      final BlazeAndroidDeployInfo deployInfo) {
    if (!ApplicationManager.getApplication().isReadAccessAllowed()) {
      return ApplicationManager.getApplication()
          .runReadAction(
              (Computable<ImmutableList<String>>) () -> getRunnersFromManifest(deployInfo));
    }

    Manifest manifest = deployInfo.getMergedManifest();
    if (manifest != null) {
      return ImmutableList.copyOf(
          manifest
              .getInstrumentations()
              .stream()
              .map(instrumentation -> instrumentation.getInstrumentationClass().getStringValue())
              .filter(Objects::nonNull)
              .collect(Collectors.toList()));
    }
    return ImmutableList.of();
  }

  @Override
  public String getDescription() {
    return "Launching instrumentation runner";
  }

  @Override
  public int getDuration() {
    return 2;
  }

  @Override
  public boolean perform(
      IDevice device, final LaunchStatus launchStatus, final ConsolePrinter printer) {
    printer.stdout("Running tests\n");

    final RemoteAndroidTestRunner runner =
        new RemoteAndroidTestRunner(testApplicationId, instrumentationTestRunner, device);
    switch (configState.getTestingType()) {
      case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_PACKAGE:
        runner.setTestPackageName(configState.getPackageName());
        break;
      case BlazeAndroidTestRunConfigurationState.TEST_CLASS:
        runner.setClassName(configState.getClassName());
        break;
      case BlazeAndroidTestRunConfigurationState.TEST_METHOD:
        runner.setMethodName(configState.getClassName(), configState.getMethodName());
        break;
    }
    runner.setDebug(waitForDebugger);
    runner.setRunOptions(configState.getExtraOptions());

    printer.stdout("$ adb shell " + runner.getAmInstrumentCommand());

    // run in a separate thread as this will block until the tests complete
    ApplicationManager.getApplication()
        .executeOnPooledThread(
            new Runnable() {
              @Override
              public void run() {
                try {
                  runner.run(new AndroidTestListener(launchStatus, printer));
                } catch (Exception e) {
                  LOG.info(e);
                  printer.stderr("Error: Unexpected exception while running tests: " + e);
                }
              }
            });

    return true;
  }
}
