/*
 * 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.binary.mobileinstall;

import com.android.ddmlib.IDevice;
import com.android.tools.idea.run.DeviceFutures;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo;
import com.google.idea.blaze.android.run.deployinfo.BlazeApkDeployInfoProtoHelper;
import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector;
import com.google.idea.blaze.android.run.runner.BlazeApkBuildStep;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.async.process.ExternalTask;
import com.google.idea.blaze.base.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.filecache.FileCaches;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.ScopedTask;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.scope.output.StatusOutput;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.util.SaveUtil;
import com.google.idea.common.experiments.BoolExperiment;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.project.Project;
import java.io.File;
import java.util.concurrent.CancellationException;
import javax.annotation.Nullable;
import org.jetbrains.android.sdk.AndroidSdkUtils;

/** Builds and installs the APK using mobile-install. */
public class BlazeApkBuildStepMobileInstall implements BlazeApkBuildStep {
  private static final BoolExperiment USE_SDK_ADB = new BoolExperiment("use.sdk.adb", true);

  private final Project project;
  private final ExecutionEnvironment env;
  private final Label label;
  private final ImmutableList<String> buildFlags;
  private final boolean useSplitApksIfPossible;
  private final SettableFuture<BlazeAndroidDeployInfo> deployInfoFuture = SettableFuture.create();

  public BlazeApkBuildStepMobileInstall(
      Project project,
      ExecutionEnvironment env,
      Label label,
      ImmutableList<String> buildFlags,
      boolean useSplitApksIfPossible) {
    this.project = project;
    this.env = env;
    this.label = label;
    this.buildFlags = buildFlags;
    this.useSplitApksIfPossible = useSplitApksIfPossible;
  }

  @Override
  public boolean build(
      BlazeContext context, BlazeAndroidDeviceSelector.DeviceSession deviceSession) {
    final ScopedTask buildTask =
        new ScopedTask(context) {
          @Override
          protected void execute(BlazeContext context) {
            boolean incrementalInstall = env.getExecutor() instanceof IncrementalInstallExecutor;

            DeviceFutures deviceFutures = deviceSession.deviceFutures;
            assert deviceFutures != null;
            IDevice device = resolveDevice(context, deviceFutures);
            if (device == null) {
              return;
            }
            BlazeCommand.Builder command =
                BlazeCommand.builder(
                    Blaze.getBuildSystemProvider(project).getBinaryPath(),
                    BlazeCommandName.MOBILE_INSTALL);
            command.addBlazeFlags(BlazeFlags.adbSerialFlags(device.getSerialNumber()));

            if (USE_SDK_ADB.getValue()) {
              File adb = AndroidSdkUtils.getAdb(project);
              if (adb != null) {
                command.addBlazeFlags(ImmutableList.of("--adb", adb.toString()));
              }
            }

            // split-apks only supported for API level 23 and above
            if (useSplitApksIfPossible && device.getVersion().getApiLevel() >= 23) {
              command.addBlazeFlags(BlazeFlags.SPLIT_APKS);
            } else if (incrementalInstall) {
              command.addBlazeFlags(BlazeFlags.INCREMENTAL);
            }
            WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);

            BlazeApkDeployInfoProtoHelper deployInfoHelper =
                new BlazeApkDeployInfoProtoHelper(project, buildFlags);
            BuildResultHelper buildResultHelper = deployInfoHelper.getBuildResultHelper();

            command
                .addTargets(label)
                .addBlazeFlags(buildFlags)
                .addBlazeFlags(buildResultHelper.getBuildFlags());

            SaveUtil.saveAllFiles();
            int retVal =
                ExternalTask.builder(workspaceRoot)
                    .addBlazeCommand(command.build())
                    .context(context)
                    .stderr(
                        buildResultHelper.stderr(
                            new IssueOutputLineProcessor(project, context, workspaceRoot)))
                    .build()
                    .run();
            FileCaches.refresh(project);

            if (retVal != 0) {
              context.setHasError();
              return;
            }

            BlazeAndroidDeployInfo deployInfo = deployInfoHelper.readDeployInfo(context);
            if (deployInfo == null) {
              IssueOutput.error("Could not read apk deploy info from build").submit(context);
              return;
            }
            deployInfoFuture.set(deployInfo);
          }
        };

    ListenableFuture<Void> buildFuture =
        BlazeExecutor.submitTask(
            project,
            String.format("Executing %s apk build", Blaze.buildSystemName(project)),
            buildTask);

    try {
      Futures.get(buildFuture, ExecutionException.class);
    } catch (ExecutionException e) {
      context.setHasError();
    } catch (CancellationException e) {
      context.setCancelled();
    }
    return context.shouldContinue();
  }

  public ListenableFuture<BlazeAndroidDeployInfo> getDeployInfo() {
    return deployInfoFuture;
  }

  @Nullable
  private static IDevice resolveDevice(BlazeContext context, DeviceFutures deviceFutures) {
    if (deviceFutures.get().size() != 1) {
      IssueOutput.error("Only one device can be used with mobile-install.").submit(context);
      return null;
    }
    context.output(new StatusOutput("Waiting for mobile-install device target..."));
    try {
      return Futures.get(Iterables.getOnlyElement(deviceFutures.get()), ExecutionException.class);
    } catch (ExecutionException | UncheckedExecutionException e) {
      IssueOutput.error("Could not get device: " + e.getMessage()).submit(context);
      return null;
    } catch (CancellationException e) {
      // The user cancelled the device launch.
      context.setCancelled();
      return null;
    }
  }
}
