/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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 org.jetbrains.idea.svn.treeConflict;

import com.intellij.CommonBundle;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diff.impl.patch.*;
import com.intellij.openapi.diff.impl.patch.formove.PatchApplier;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.MessageDialogBuilder;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.changes.committed.CommittedChangesTreeBrowser;
import com.intellij.openapi.vcs.changes.patch.ApplyPatchDifferentiatedDialog;
import com.intellij.openapi.vcs.changes.patch.ApplyPatchExecutor;
import com.intellij.openapi.vcs.changes.patch.ApplyPatchMode;
import com.intellij.openapi.vcs.changes.patch.FilePatchInProgress;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.SmartList;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.continuation.Continuation;
import com.intellij.util.continuation.ContinuationContext;
import com.intellij.util.continuation.TaskDescriptor;
import com.intellij.util.continuation.Where;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.*;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.conflict.TreeConflictDescription;
import org.jetbrains.idea.svn.history.SvnChangeList;
import org.jetbrains.idea.svn.history.SvnRepositoryLocation;
import org.tmatesoft.svn.core.wc.SVNRevision;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: Irina.Chernushina
 * Date: 5/18/12
 * Time: 2:44 PM
 */
public class MergeFromTheirsResolver {
  private final SvnVcs myVcs;
  private final TreeConflictDescription myDescription;
  private final Change myChange;
  private final FilePath myOldFilePath;
  private final FilePath myNewFilePath;
  private final String myOldPresentation;
  private final String myNewPresentation;
  private final SvnRevisionNumber myCommittedRevision;
  private Boolean myAdd;

  private final List<Change> myTheirsChanges;
  private final List<Change> myTheirsBinaryChanges;
  private final List<VcsException> myWarnings;
  private List<TextFilePatch> myTextPatches;
  private VirtualFile myBaseForPatch;

  public MergeFromTheirsResolver(SvnVcs vcs, TreeConflictDescription description, Change change, SvnRevisionNumber revision) {
    myVcs = vcs;
    myDescription = description;
    myChange = change;
    myCommittedRevision = revision;
    myOldFilePath = myChange.getBeforeRevision().getFile();
    myNewFilePath = myChange.getAfterRevision().getFile();
    myBaseForPatch = ChangesUtil.findValidParentAccurately(myNewFilePath);
    myOldPresentation = TreeConflictRefreshablePanel.filePath(myOldFilePath);
    myNewPresentation = TreeConflictRefreshablePanel.filePath(myNewFilePath);

    myTheirsChanges = new ArrayList<Change>();
    myTheirsBinaryChanges = new ArrayList<Change>();
    myWarnings = new ArrayList<VcsException>();
    myTextPatches = Collections.emptyList();
  }

  public void execute() {
    int ok = Messages.showOkCancelDialog(myVcs.getProject(), (myChange.isMoved() ?
      SvnBundle.message("confirmation.resolve.tree.conflict.merge.moved", myOldPresentation, myNewPresentation) :
      SvnBundle.message("confirmation.resolve.tree.conflict.merge.renamed", myOldPresentation, myNewPresentation)),
                                         TreeConflictRefreshablePanel.TITLE, Messages.getQuestionIcon());
    if (Messages.OK != ok) return;

    FileDocumentManager.getInstance().saveAllDocuments();
    //final String name = "Merge changes from theirs for: " + myOldPresentation;

    final Continuation fragmented = Continuation.createFragmented(myVcs.getProject(), false);
    fragmented.addExceptionHandler(VcsException.class, new Consumer<VcsException>() {
      @Override
      public void consume(VcsException e) {
        myWarnings.add(e);
        if (e.isWarning()) {
          return;
        }
        AbstractVcsHelper.getInstance(myVcs.getProject()).showErrors(myWarnings, TreeConflictRefreshablePanel.TITLE);
      }
    });

    final List<TaskDescriptor> tasks = new SmartList<TaskDescriptor>();
    tasks.add(myDescription.isDirectory() ? new PreloadChangesContentsForDir() : new PreloadChangesContentsForFile());
    tasks.add(new ConvertTextPaths());
    tasks.add(new PatchCreator());
    tasks.add(new SelectPatchesInApplyPatchDialog());
    tasks.add(new SelectBinaryFiles());

    fragmented.run(tasks);
  }

  private void appendResolveConflictToContext(final ContinuationContext context) {
    context.next(new ResolveConflictInSvn());
  }

  private void appendTailToContextLast(final ContinuationContext context) {
    context.last(new ApplyBinaryChanges(), new FinalNotification());
  }

  private List<Change> filterOutBinary(List<Change> paths) {
    List<Change> result = null;
    for (Iterator<Change> iterator = paths.iterator(); iterator.hasNext(); ) {
      final Change change = iterator.next();
      if (ChangesUtil.isBinaryChange(change)) {
        result = (result == null ? new SmartList<Change>() : result);
        result.add(change);
        iterator.remove();
      }
    }
    return result;
  }

  private class FinalNotification extends TaskDescriptor {
    private FinalNotification() {
      super("", Where.AWT);
    }

    @Override
    public void run(ContinuationContext context) {
      final StringBuilder message = new StringBuilder().append("Theirs changes merged for ").append(myOldPresentation);
      VcsBalloonProblemNotifier.showOverChangesView(myVcs.getProject(), message.toString(), MessageType.INFO);
      if (! myWarnings.isEmpty()) {
        AbstractVcsHelper.getInstance(myVcs.getProject()).showErrors(myWarnings, TreeConflictRefreshablePanel.TITLE);
      }
    }
  }

  private class ResolveConflictInSvn extends TaskDescriptor {
    private ResolveConflictInSvn() {
      super("Accepting working state", Where.POOLED);
    }

    @Override
    public void run(ContinuationContext context) {
      try {
        new SvnTreeConflictResolver(myVcs, myOldFilePath, myCommittedRevision, null).resolveSelectMineFull(myDescription);
      }
      catch (VcsException e1) {
        context.handleException(e1, false);
      }
    }
  }

  private class ConvertTextPaths extends TaskDescriptor {
    private ConvertTextPaths() {
      super("", Where.AWT);
    }

    @Override
    public void run(ContinuationContext context) {
      initAddOption();
      List<Change> convertedChanges = new SmartList<Change>();
      try {
        // revision contents is preloaded, so ok to call in awt
        convertedChanges = convertPaths(myTheirsChanges);
      }
      catch (VcsException e) {
        context.handleException(e, true);
      }
      myTheirsChanges.clear();
      myTheirsChanges.addAll(convertedChanges);
    }
  }

  private class SelectPatchesInApplyPatchDialog extends TaskDescriptor {
    private SelectPatchesInApplyPatchDialog() {
      super("", Where.AWT);
    }

    @Override
    public void run(ContinuationContext context) {
      final ChangeListManager clManager = ChangeListManager.getInstance(myVcs.getProject());
      final LocalChangeList changeList = clManager.getChangeList(myChange);
      final ApplyPatchDifferentiatedDialog dialog = new ApplyPatchDifferentiatedDialog(myVcs.getProject(),
        new TreeConflictApplyTheirsPatchExecutor(myVcs, context, myBaseForPatch),
        Collections.<ApplyPatchExecutor>singletonList(new ApplyPatchSaveToFileExecutor(myVcs.getProject(), myBaseForPatch)),
        ApplyPatchMode.APPLY_PATCH_IN_MEMORY, myTextPatches, changeList);
      context.suspend();
      dialog.show();
    }
  }

  private class TreeConflictApplyTheirsPatchExecutor implements ApplyPatchExecutor {
    private final SvnVcs myVcs;
    private final ContinuationContext myInner;
    private final VirtualFile myBaseDir;

    public TreeConflictApplyTheirsPatchExecutor(SvnVcs vcs, ContinuationContext inner, final VirtualFile baseDir) {
      myVcs = vcs;
      myInner = inner;
      myBaseDir = baseDir;
    }

    @Override
    public String getName() {
      return "Apply patch";
    }

    @Override
    public void apply(MultiMap<VirtualFile, FilePatchInProgress> patchGroups, LocalChangeList localList, String fileName,
                      TransparentlyFailedValueI<Map<String, Map<String, CharSequence>>, PatchSyntaxException> additionalInfo) {
      final List<FilePatch> patches;
      try {
        patches = ApplyPatchSaveToFileExecutor.patchGroupsToOneGroup(patchGroups, myBaseDir);
      }
      catch (IOException e) {
        myInner.handleException(e, true);
        return;
      }

      final PatchApplier<BinaryFilePatch> patchApplier =
        new PatchApplier<BinaryFilePatch>(myVcs.getProject(), myBaseDir, patches, localList, null, null);
      patchApplier.scheduleSelf(false, myInner, true);  // 3
      boolean thereAreCreations = false;
      for (FilePatch patch : patches) {
        if (patch.isNewFile() || ! Comparing.equal(patch.getAfterName(), patch.getBeforeName())) {
          thereAreCreations = true;
          break;
        }
      }
      if (thereAreCreations) {
        // restore deletion of old directory:
        myInner.next(new DirectoryAddition());  // 2
      }
      appendResolveConflictToContext(myInner);  // 1
      appendTailToContextLast(myInner); // 4
      myInner.ping();
    }
  }

  private class DirectoryAddition extends TaskDescriptor {
    private DirectoryAddition() {
      super("Adding " + myOldPresentation + " to Subversion", Where.POOLED);
    }

    @Override
    public void run(ContinuationContext context) {
      try {
        // TODO: Previously SVNKit client was invoked with mkDir=true option - so corresponding directory would be created. Now mkDir=false
        // TODO: is used. Command line also does not support automatic directory creation.
        // TODO: Need to check additionally if there are cases when directory does not exist and add corresponding code.
        myVcs.getFactory(myOldFilePath.getIOFile()).createAddClient()
          .add(myOldFilePath.getIOFile(), Depth.EMPTY, true, false, true, null);
      }
      catch (VcsException e) {
        context.handleException(e, true);
      }
    }
  }

  private class PatchCreator extends TaskDescriptor {
    private PatchCreator() {
      super("Creating patch for theirs changes", Where.POOLED);
    }

    @Override
    public void run(ContinuationContext context) {
      final Project project = myVcs.getProject();
      final List<FilePatch> patches;
      try {
        patches = IdeaTextPatchBuilder.buildPatch(project, myTheirsChanges, myBaseForPatch.getPath(), false);
        myTextPatches = ObjectsConvertor.convert(patches, new Convertor<FilePatch, TextFilePatch>() {
          @Override
          public TextFilePatch convert(FilePatch o) {
            return (TextFilePatch)o;
          }
        });
      }
      catch (VcsException e) {
        context.handleException(e, true);
      }
    }
  }

  private class SelectBinaryFiles extends TaskDescriptor {
    private SelectBinaryFiles() {
      super("", Where.AWT);
    }

    @Override
    public void run(ContinuationContext context) {
      if (myTheirsBinaryChanges.isEmpty()) return;
      final List<Change> converted;
      try {
        converted = convertPaths(myTheirsBinaryChanges);
      }
      catch (VcsException e) {
        context.handleException(e, true);
        return;
      }
      if (converted.isEmpty()) return;
      final Map<FilePath, Change> map = new HashMap<FilePath, Change>();
      for (Change change : converted) {
        map.put(ChangesUtil.getFilePath(change), change);
      }
      final Collection<FilePath> selected = chooseBinaryFiles(converted, map.keySet());
      myTheirsBinaryChanges.clear();
      for (FilePath filePath : selected) {
        myTheirsBinaryChanges.add(map.get(filePath));
      }
    }
  }

  private class ApplyBinaryChanges extends TaskDescriptor {
    private ApplyBinaryChanges() {
      super("", Where.AWT);
    }

    @Override
    public void run(final ContinuationContext context) {
      if (myTheirsBinaryChanges.isEmpty()) return;
      final Application application = ApplicationManager.getApplication();
      final List<FilePath> dirtyPaths = new ArrayList<FilePath>();
      for (final Change change : myTheirsBinaryChanges) {
        try {
          application.runWriteAction(new ThrowableComputable<Void, VcsException>() {
            @Override
            public Void compute() throws VcsException {
              try {
                if (change.getAfterRevision() == null) {
                  final FilePath path = change.getBeforeRevision().getFile();
                  dirtyPaths.add(path);
                  final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(path.getIOFile());
                  if (file == null) {
                    context.handleException(new VcsException("Can not delete file: " + file.getPath(), true), false);
                    return null;
                  }
                  file.delete(TreeConflictRefreshablePanel.class);
                }
                else {
                  final FilePath file = change.getAfterRevision().getFile();
                  dirtyPaths.add(file);
                  final String parentPath = file.getParentPath().getPath();
                  final VirtualFile parentFile = VfsUtil.createDirectoryIfMissing(parentPath);
                  if (parentFile == null) {
                    context.handleException(new VcsException("Can not create directory: " + parentPath, true), false);
                    return null;
                  }
                  final VirtualFile child = parentFile.createChildData(TreeConflictRefreshablePanel.class, file.getName());
                  if (child == null) {
                    context.handleException(new VcsException("Can not create file: " + file.getPath(), true), false);
                    return null;
                  }
                  final BinaryContentRevision revision = (BinaryContentRevision)change.getAfterRevision();
                  final byte[] content = revision.getBinaryContent();
                  // actually it was the fix for IDEA-91572 Error saving merged data: Argument 0 for @NotNull parameter of > com/intellij/
                  if (content == null) {
                    context.handleException(new VcsException("Can not load Theirs content for file " + file.getPath()), false);
                    return null;
                  }
                  child.setBinaryContent(content);
                }
              }
              catch (IOException e) {
                throw new VcsException(e);
              }
              return null;
            }
          });
        }
        catch (VcsException e) {
          context.handleException(e, true);
          return;
        }
      }
      VcsDirtyScopeManager.getInstance(myVcs.getProject()).filePathsDirty(dirtyPaths, null);
    }
  }

  private Collection<FilePath> chooseBinaryFiles(List<Change> converted, Set<FilePath> paths) {
    String singleMessage = "";
    if (paths.size() == 1) {
      final Change change = converted.get(0);
      final FileStatus status = change.getFileStatus();
      final FilePath path = ChangesUtil.getFilePath(change);
      final String stringPath = TreeConflictRefreshablePanel.filePath(path);
      if (FileStatus.DELETED.equals(status)) {
        singleMessage = "Delete binary file " + stringPath + " (according to theirs changes)?";
      } else if (FileStatus.ADDED.equals(status)) {
        singleMessage = "Create binary file " + stringPath + " (according to theirs changes)?";
      } else {
        singleMessage = "Apply changes to binary file " + stringPath + " (according to theirs changes)?";
      }
    }
    return AbstractVcsHelper.getInstance(myVcs.getProject()).selectFilePathsToProcess(new ArrayList<FilePath>(paths),
      TreeConflictRefreshablePanel.TITLE, "Select binary files to patch", TreeConflictRefreshablePanel.TITLE,
      singleMessage, new VcsShowConfirmationOption() {

      @Override
      public Value getValue() {
        return null;
      }

      @Override
      public void setValue(Value value) {
      }

      @Override
      public boolean isPersistent() {
        return false;
      }
    });
  }

  private List<Change> convertPaths(List<Change> changesForPatch) throws VcsException {
    initAddOption();
    final List<Change> changes = new ArrayList<Change>();
    for (Change change : changesForPatch) {
      if (! isUnderOldDir(change, myOldFilePath)) continue;
      ContentRevision before = null;
      ContentRevision after = null;
      if (change.getBeforeRevision() != null) {
        before = new SimpleContentRevision(change.getBeforeRevision().getContent(),
          rebasePath(myOldFilePath, myNewFilePath, change.getBeforeRevision().getFile()),
          change.getBeforeRevision().getRevisionNumber().asString());
      }
      if (change.getAfterRevision() != null) {
        // if addition or move - do not move to the new path
        if (myAdd && (change.getBeforeRevision() == null || change.isMoved() || change.isRenamed())) {
          after = change.getAfterRevision();
        } else {
          after = new SimpleContentRevision(change.getAfterRevision().getContent(),
                                            rebasePath(myOldFilePath, myNewFilePath, change.getAfterRevision().getFile()),
                                            change.getAfterRevision().getRevisionNumber().asString());
        }
      }
      changes.add(new Change(before, after));
    }
    return changes;
  }

  private boolean isUnderOldDir(Change change, FilePath path) {
    if (change.getBeforeRevision() != null) {
      final boolean isUnder = FileUtil.isAncestor(path.getIOFile(), change.getBeforeRevision().getFile().getIOFile(), true);
      if (isUnder) {
        return true;
      }
    }
    if (change.getAfterRevision() != null) {
      final boolean isUnder = FileUtil.isAncestor(path.getIOFile(), change.getAfterRevision().getFile().getIOFile(), true);
      if (isUnder) {
        return isUnder;
      }
    }
    return false;
  }

  private FilePath rebasePath(final FilePath oldBase, final FilePath newBase, final FilePath path) {
    final String relativePath = FileUtil.getRelativePath(oldBase.getPath(), path.getPath(), File.separatorChar);
    //if (StringUtil.isEmptyOrSpaces(relativePath)) return path;
    return ((FilePathImpl) newBase).createChild(relativePath, path.isDirectory());
  }

  private class PreloadChangesContentsForFile extends TaskDescriptor {
    private PreloadChangesContentsForFile() {
      super("Getting base and theirs revisions content", Where.POOLED);
    }

    @Override
    public void run(ContinuationContext context) {
      final SvnContentRevision base = SvnContentRevision.createBaseRevision(myVcs, myNewFilePath, myCommittedRevision.getRevision());
      final SvnContentRevision remote = SvnContentRevision.createRemote(myVcs, myOldFilePath, SVNRevision.create(
                                                                          myDescription.getSourceRightVersion().getPegRevision()));
      try {
        final ContentRevision newBase = new SimpleContentRevision(base.getContent(), myNewFilePath, base.getRevisionNumber().asString());
        final ContentRevision newRemote = new SimpleContentRevision(remote.getContent(), myNewFilePath, remote.getRevisionNumber().asString());
        myTheirsChanges.add(new Change(newBase, newRemote));
      }
      catch (VcsException e) {
        context.handleException(e, true);
      }
    }
  }

  private class PreloadChangesContentsForDir extends TaskDescriptor {
    private PreloadChangesContentsForDir() {
      super("Getting base and theirs revisions content", Where.POOLED);
    }

    @Override
    public void run(ContinuationContext context) {
      final List<Change> changesForPatch;
      try {
        final List<CommittedChangeList> lst = loadSvnChangeListsForPatch(myDescription);
        changesForPatch = CommittedChangesTreeBrowser.collectChanges(lst, true);
        for (Change change : changesForPatch) {
          if (change.getBeforeRevision() != null) {
            preloadRevisionContents(change.getBeforeRevision());
          }
          if (change.getAfterRevision() != null) {
            preloadRevisionContents(change.getAfterRevision());
          }
        }
      }
      catch (VcsException e) {
        context.handleException(e, true);
        return;
      }
      final List<Change> binaryChanges = filterOutBinary(changesForPatch);
      if (binaryChanges != null && ! binaryChanges.isEmpty()) {
        myTheirsBinaryChanges.addAll(binaryChanges);
      }
      if (! changesForPatch.isEmpty()) {
        myTheirsChanges.addAll(changesForPatch);
      }
    }
  }

  private void preloadRevisionContents(ContentRevision cr) throws VcsException {
    if (cr instanceof BinaryContentRevision) {
      ((BinaryContentRevision) cr).getBinaryContent();
    } else {
      cr.getContent();
    }
  }

  private List<CommittedChangeList> loadSvnChangeListsForPatch(TreeConflictDescription description) throws VcsException {
    long max = description.getSourceRightVersion().getPegRevision();
    long min = description.getSourceLeftVersion().getPegRevision();

    final ChangeBrowserSettings settings = new ChangeBrowserSettings();
    settings.USE_CHANGE_BEFORE_FILTER = settings.USE_CHANGE_AFTER_FILTER = true;
    settings.CHANGE_BEFORE = "" + max;
    settings.CHANGE_AFTER = "" + min;
    final List<SvnChangeList> committedChanges = myVcs.getCachingCommittedChangesProvider().getCommittedChanges(
      settings, new SvnRepositoryLocation(description.getSourceRightVersion().getRepositoryRoot().toString()), 0);
    final List<CommittedChangeList> lst = new ArrayList<CommittedChangeList>(committedChanges.size() - 1);
    for (SvnChangeList change : committedChanges) {
      if (change.getNumber() == min) {
        continue;
      }
      lst.add(change);
    }
    return lst;
  }

  private void initAddOption() {
    ApplicationManager.getApplication().assertIsDispatchThread();
    if (myAdd == null) {
      myAdd = getAddedFilesPlaceOption();
    }
  }

  private boolean getAddedFilesPlaceOption() {
    final SvnConfiguration configuration = SvnConfiguration.getInstance(myVcs.getProject());
    boolean add = Boolean.TRUE.equals(configuration.isKeepNewFilesAsIsForTreeConflictMerge());
    if (configuration.isKeepNewFilesAsIsForTreeConflictMerge() != null) {
      return add;
    }
    if (!containAdditions(myTheirsChanges) && !containAdditions(myTheirsBinaryChanges)) {
      return false;
    }
    return Messages.YES == MessageDialogBuilder.yesNo(TreeConflictRefreshablePanel.TITLE, "Keep newly created file(s) in their original place?").yesText("Keep").noText("Move").doNotAsk(
      new DialogWrapper.DoNotAskOption() {
        @Override
        public boolean isToBeShown() {
          return true;
        }

        @Override
        public void setToBeShown(boolean value, int exitCode) {
          if (!value) {
            if (exitCode == 0) {
              // yes
              configuration.setKeepNewFilesAsIsForTreeConflictMerge(true);
            }
            else {
              configuration.setKeepNewFilesAsIsForTreeConflictMerge(false);
            }
          }
        }

        @Override
        public boolean canBeHidden() {
          return true;
        }

        @Override
        public boolean shouldSaveOptionsOnCancel() {
          return true;
        }

        @NotNull
        @Override
        public String getDoNotShowMessage() {
          return CommonBundle.message("dialog.options.do.not.ask");
        }
      }).show();
  }

  private boolean containAdditions(final List<Change> changes) {
    boolean addFound = false;
    for (Change change : changes) {
      if (change.getBeforeRevision() == null || change.isMoved() || change.isRenamed()) {
        addFound = true;
        break;
      }
    }
    return addFound;
  }
}
