// Copyright 2000-2019 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.vcs.changes.actions;

import com.intellij.openapi.ListSelection;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.AnActionExtensionProvider;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.CurrentContentRevision;
import com.intellij.openapi.vcs.changes.committed.CommittedChangesBrowserUseCase;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

import static com.intellij.openapi.vcs.changes.actions.diff.ShowDiffAction.showDiffForChange;

public class ShowDiffWithLocalAction implements AnActionExtensionProvider {
  private final boolean myUseBeforeVersion;

  @SuppressWarnings("unused")
  public ShowDiffWithLocalAction() {
    this(false);
  }

  public ShowDiffWithLocalAction(boolean useBeforeVersion) {
    myUseBeforeVersion = useBeforeVersion;
  }

  @Override
  public boolean isActive(@NotNull AnActionEvent e) {
    return e.getData(VcsDataKeys.CHANGES_SELECTION) != null;
  }

  @Override
  public void actionPerformed(@NotNull AnActionEvent e) {
    Project project = e.getRequiredData(CommonDataKeys.PROJECT);
    if (ChangeListManager.getInstance(project).isFreezedWithNotification(null)) return;
    ListSelection<Change> selection = e.getRequiredData(VcsDataKeys.CHANGES_SELECTION);

    ListSelection<Change> changesToLocal = selection.map(change -> getChangeWithLocal(change));

    if (!changesToLocal.isEmpty()) {
      showDiffForChange(project, changesToLocal);
    }
  }

  @Override
  public void update(@NotNull final AnActionEvent e) {
    Project project = e.getData(CommonDataKeys.PROJECT);
    ListSelection<Change> selection = e.getData(VcsDataKeys.CHANGES_SELECTION);
    boolean isInAir = CommittedChangesBrowserUseCase.IN_AIR.equals(e.getData(CommittedChangesBrowserUseCase.DATA_KEY));

    e.getPresentation().setEnabled(project != null && selection != null && !isInAir && canShowDiff(selection.getList()));
  }

  @Nullable
  private Change getChangeWithLocal(@NotNull Change c) {
    ContentRevision revision = myUseBeforeVersion ? c.getBeforeRevision() : c.getAfterRevision();
    ContentRevision otherRevision = myUseBeforeVersion ? c.getAfterRevision() : c.getBeforeRevision();

    VirtualFile file = getLocalVirtualFileFor(revision);
    if (file == null) file = getLocalVirtualFileFor(otherRevision); // handle renames gracefully

    ContentRevision localRevision = file != null ? CurrentContentRevision.create(VcsUtil.getFilePath(file)) : null;
    if (revision == null && localRevision == null) return null;

    return new Change(revision, localRevision);
  }

  private boolean canShowDiff(@NotNull List<? extends Change> changes) {
    return ContainerUtil.exists(changes, c -> getChangeWithLocal(c) != null);
  }

  @Nullable
  private static VirtualFile getLocalVirtualFileFor(@Nullable ContentRevision revision) {
    if (revision == null) return null;
    FilePath filePath = revision.getFile();
    if (filePath.isNonLocal() || filePath.isDirectory()) return null;
    return filePath.getVirtualFile();
  }

  public static class ShowDiffBeforeWithLocalAction extends ShowDiffWithLocalAction {
    public ShowDiffBeforeWithLocalAction() {
      super(true);
    }
  }
}

@@ -209,24 +209,111 @@
 lij.
-openapi.ListSele
+icons.AllIcons;%0Aimport com.intellij.openapi.ListSelection;%0Aimport com.intellij.openapi.actionSystem.AnA
 ctio
@@ -488,32 +488,135 @@
 CommonDataKeys;%0A
+import com.intellij.openapi.actionSystem.ex.ActionUtil;%0Aimport com.intellij.openapi.project.DumbAware;%0A
 import com.intel
@@ -1383,55 +1383,298 @@
 e;%0A%0A
-public class ShowDiffWithLocalAction implements
+// via openapi.vcs.history.actions.ShowDiffBeforeWithLocalAction.ExtensionProvider%0A// Extending AnAction is left for compatibility with plugins that instantiate this class directly (instead of using ActionManager).%0Apublic class ShowDiffWithLocalAction extends AnAction implements DumbAware,
  AnA
@@ -1827,16 +1827,78 @@
 false);%0A
+    getTemplatePresentation().setIcon(AllIcons.Actions.Diff);%0A
   %7D%0A%0A  p
@@ -1951,24 +1951,24 @@
 eVersion) %7B%0A
-
     myUseBef
@@ -1998,16 +1998,124 @@
 ersion;%0A
+    ActionUtil.copyFrom(this, useBeforeVersion ? %22Vcs.ShowDiffWithLocal.Before%22 : %22Vcs.ShowDiffWithLocal%22);%0A
   %7D%0A%0A  @
@@ -4308,32 +4308,161 @@
 ualFile();%0A  %7D%0A%0A
+  @SuppressWarnings(%22ComponentNotRegistered%22) // via openapi.vcs.history.actions.ShowDiffBeforeWithLocalAction.ExtensionProvider%0A
   public static 

Revert "vcs: remove unnecessary inheritance from AnAction"