/*
 * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 */
package com.intellij.openapi.command.impl;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationStarterEx;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.updateSettings.impl.PluginDownloader;
import com.intellij.openapi.updateSettings.impl.UpdateChecker;
import com.intellij.openapi.updateSettings.impl.UpdateInstaller;
import com.intellij.openapi.updateSettings.impl.UpdateSettings;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.BuildNumber;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

import static com.intellij.util.containers.ContainerUtil.newTroveSet;

/**
 * @author Konstantin Bulenkov
 */
public class UpdatePluginsApp extends ApplicationStarterEx {
  @Override
  public boolean isHeadless() {
    return true;
  }

  @Override
  public String getCommandName() {
    return "update";
  }

  @Override
  public void premain(String[] args) {

  }

  @Override
  public void main(String[] args) {
    Set<String> pluginsToUpdate = getPluginsToUpdate(args);
    ActionCallback callback = new ActionCallback()
      .doWhenDone(() -> System.exit(0))
      .doWhenRejected(() -> System.exit(1));

    Runnable update = () -> updateAllPlugins(callback, pluginsToUpdate, getBuildNumber(args, callback));
    ApplicationManager.getApplication().executeOnPooledThread(update);
  }

  @Nullable
  private static Set<String> getPluginsToUpdate(String[] args) {
    if (args.length < 2) return null;
    //skip "update" command and read plugin ids
    final int fromIndex = "-b".equals(args[1]) ? 3 : 1;
    return newTroveSet(Arrays.asList(args).subList(fromIndex, args.length));
  }

  @NotNull
  private static BuildNumber getBuildNumber(final String[] args, final ActionCallback callback) {
    if (args.length > 2 && "-b".equals(args[1])) {
      final BuildNumber buildNumber = BuildNumber.fromString(args[2]);
      if (buildNumber != null) {
        return buildNumber;
      }
      else {
        log("Invalid build number: " + args[2]);
        callback.setRejected();
      }
    }
    return BuildNumber.currentVersion();
  }

  private static void updateAllPlugins(ActionCallback callback, @Nullable Set<String> plugins, BuildNumber buildNumber) {
    Collection<PluginDownloader> availableUpdates = UpdateChecker.checkPluginsUpdate(UpdateSettings.getInstance(),
                                                                                    new EmptyProgressIndicator(),
                                                                                    new HashSet<>(),
                                                                                    buildNumber);
    if (availableUpdates == null) {
      log("All plugins up to date.");
      callback.setDone();
      return;
    }

    Collection<PluginDownloader> pluginsToUpdate = plugins == null || plugins.isEmpty()
                                                   ? availableUpdates
                                                   : availableUpdates.stream()
                                                     .filter(downloader -> plugins.contains(downloader.getPluginId()))
                                                     .collect(Collectors.toList());


    log("Plugins to update:");
    pluginsToUpdate.forEach(d -> log("\t" + d.getPluginName()));

    if (UpdateInstaller.installPluginUpdates(pluginsToUpdate, new EmptyProgressIndicator())) {
      callback.setDone();
    } else {
      log("Update failed");
      callback.setRejected();
    }
  }

  private static void log(String msg) {
    System.out.println(msg);
  }
}
@@ -725,50 +725,8 @@
 er;%0A
-import org.jetbrains.annotations.NotNull;%0A
 impo
@@ -787,17 +787,20 @@
 il.Array
-s
+List
 ;%0Aimport
@@ -865,18 +865,19 @@
 va.util.
-Se
+Lis
 t;%0Aimpor
@@ -912,79 +912,8 @@
 s;%0A%0A
-import static com.intellij.util.containers.ContainerUtil.newTroveSet;%0A%0A
 /**%0A
@@ -1256,18 +1256,19 @@
 ) %7B%0A    
-Se
+Lis
 t%3CString
@@ -1317,16 +1317,18 @@
 s);%0A    
+ 
+ 
 ActionCa
@@ -1368,24 +1368,26 @@
 ack()%0A      
+  
 .doWhenDone(
@@ -1408,16 +1408,18 @@
 xit(0))%0A
+  
       .d
@@ -1460,16 +1460,18 @@
 );%0A%0A    
+  
 Runnable
@@ -1532,43 +1532,13 @@
 date
-, getBuildNumber(args, callback)
 );%0A
+  
     
@@ -1638,18 +1638,19 @@
  static 
-Se
+Lis
 t%3CString
@@ -1733,170 +1733,54 @@
     
-//skip %22update%22 command and read plugin ids%0A    final int fromIndex = %22-b%22.equals(args%5B1%5D) ? 3 : 1;%0A    return newTroveSet(
+ArrayList%3CString%3E pluginIds = new 
 Array
-s.as
 List
+%3C%3E
 (
-args).subList(fromIndex, 
 args
@@ -1790,327 +1790,104 @@
 ngth
-)
+ - 1
 );%0A  
-%7D%0A%0A  @NotNull%0A  private static BuildNumber getBuildNumber(final String%5B%5D args, final ActionCallback callback) %7B%0A    if (args.length %3E 2 && %22-b%22.equals(args%5B1%5D)) %7B%0A      final BuildNumber buildNumber = BuildNumber.fromString(args%5B2%5D);%0A      if (buildNumber != null) %7B%0A        return buildNumber;%0A      %7D%0A      else
+  //skip %22update%22 command and read plugin ids%0A    for (int i = 1; i %3C args.length; i++)
  %7B%0A 
@@ -1895,55 +1895,43 @@
     
- 
- log(%22Invalid build number: %22 +
+pluginIds.add(i - 1,
  args%5B
-2
+i
 %5D);%0A    
     
@@ -1930,89 +1930,30 @@
     
-    callback.setRejected();%0A      %7D%0A    %7D%0A    return BuildNumber.currentVersion()
+%7D%0A    return pluginIds
 ;%0A  
@@ -2029,18 +2029,19 @@
 ullable 
-Se
+Lis
 t%3CString
@@ -2053,33 +2053,8 @@
 gins
-, BuildNumber buildNumber
 ) %7B%0A
@@ -2467,17 +2467,17 @@
         
-b
+B
 uildNumb
@@ -2478,16 +2478,33 @@
 ldNumber
+.currentVersion()
 );%0A    i

Revert "add "-b" (build number) parameter to Update Plugins command"