/*
 * Copyright 2000-2012 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;

import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vcs.rollback.RollbackProgressListener;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NonNls;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * @author yole
 */
public class SvnRenameTest extends Svn17TestCase {
  @NonNls private static final String LOG_SEPARATOR = "------------------------------------------------------------------------\n";
  @NonNls private static final String LOG_SEPARATOR_START = "-------------";

  public SvnRenameTest() {
    myInitChangeListManager = false;
  }

  @Test
  public void testSimpleRename() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile a = createFileInCommand("a.txt", "test");
    checkin();

    renameFileInCommand(a, "b.txt");
    verifySorted(runSvn("status"), "A + b.txt", "D a.txt");
  }

  // IDEADEV-18844
  @Test
  public void testRenameReplace() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile a = createFileInCommand("a.txt", "old");
    final VirtualFile aNew = createFileInCommand("aNew.txt", "new");
    checkin();

    renameFileInCommand(a, "aOld.txt");
    renameFileInCommand(aNew, "a.txt");
    final ProcessOutput result = runSvn("status");
    verifySorted(result, "A + aOld.txt", "D aNew.txt", "R + a.txt");
  }

  // IDEADEV-16251
  @Test
  public void testRenameAddedPackage() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile dir = createDirInCommand(myWorkingCopyDir, "child");
    createFileInCommand(dir, "a.txt", "content");
    renameFileInCommand(dir, "newchild");
    verifySorted(runSvn("status"), "A newchild", "A newchild" + File.separatorChar + "a.txt");
  }

  // IDEADEV-8091
  @Test
  public void testDoubleRename() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile a = createFileInCommand("a.txt", "test");
    checkin();

    renameFileInCommand(a, "b.txt");
    renameFileInCommand(a, "c.txt");
    verifySorted(runSvn("status"), "A + c.txt", "D a.txt");
  }

  // IDEADEV-15876
  @Test
  public void testRenamePackageWithChildren() throws Exception {
    final VirtualFile child = prepareDirectoriesForRename();

    renameFileInCommand(child, "childnew");
    final ProcessOutput result = runSvn("status");
    verifySorted(result, "A + childnew",
                 "D child",
                 "D child" + File.separatorChar + "a.txt",
                 "D child" + File.separatorChar + "grandChild",
                 "D child" + File.separatorChar + "grandChild" + File.separatorChar + "b.txt");

    refreshVfs();   // wait for end of refresh operations initiated from SvnFileSystemListener
    final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject);
    insideInitializedChangeListManager(changeListManager, new Runnable() {
      @Override
      public void run() {
        changeListManager.ensureUpToDate(false);
        List<Change> changes = new ArrayList<Change>(changeListManager.getDefaultChangeList().getChanges());
        Assert.assertEquals(4, changes.size());
        sortChanges(changes);
        verifyChange(changes.get(0), "child", "childnew");
        verifyChange(changes.get(1), "child" + File.separatorChar + "a.txt", "childnew" + File.separatorChar + "a.txt");
        verifyChange(changes.get(2), "child" + File.separatorChar + "grandChild", "childnew" + File.separatorChar + "grandChild");
        verifyChange(changes.get(3), "child" + File.separatorChar + "grandChild" + File.separatorChar + "b.txt", "childnew" + File.separatorChar + "grandChild" + File.separatorChar + "b.txt");
      }
    });

    // there is no such directory any more
    /*VirtualFile oldChild = myWorkingCopyDir.findChild("child");
    if (oldChild == null) {
      myWorkingCopyDir.refresh(false, true);
      oldChild = myWorkingCopyDir.findChild("child");
    }
    Assert.assertEquals(FileStatus.DELETED, changeListManager.getStatus(oldChild));*/
  }

  private void insideInitializedChangeListManager(final ChangeListManager changeListManager, final Runnable runnable) {
    ((ChangeListManagerImpl) changeListManager).projectOpened();
    try {
      runnable.run();
    } finally {
      ((ChangeListManagerImpl) changeListManager).projectClosed();
      ((ChangeListManagerImpl) changeListManager).stopEveryThingIfInTestMode();
    }
  }

  private VirtualFile prepareDirectoriesForRename() throws IOException {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile child = createDirInCommand(myWorkingCopyDir, "child");
    final VirtualFile grandChild = createDirInCommand(child, "grandChild");
    createFileInCommand(child, "a.txt", "a");
    createFileInCommand(grandChild, "b.txt", "b");
    checkin();
    return child;
  }

  // IDEADEV-19065
  @Test
  public void testCommitAfterRenameDir() throws Exception {
    final VirtualFile child = prepareDirectoriesForRename();

    renameFileInCommand(child, "newchild");
    checkin();

    final ProcessOutput runResult = runSvn("log", "-q", "newchild/a.txt");
    verify(runResult);
    final List<String> lines = StringUtil.split(runResult.getStdout(), "\n");
    for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
      final String next = iterator.next();
      if (next.startsWith(LOG_SEPARATOR_START)) {
        iterator.remove();
      }
    }
    Assert.assertEquals(2, lines.size());
    Assert.assertTrue(lines.get(0).startsWith("r2 |"));
    Assert.assertTrue(lines.get(1).startsWith("r1 |"));
  }

  // todo - undo; undo after commit
  // IDEADEV-9755
  @Test
  public void testRollbackRenameDir() throws Exception {
    final VirtualFile child = prepareDirectoriesForRename();
    renameFileInCommand(child, "newchild");

    final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject);
    insideInitializedChangeListManager(changeListManager, new Runnable() {
      @Override
      public void run() {
        changeListManager.ensureUpToDate(false);
        final Change change = changeListManager.getChange(myWorkingCopyDir.findChild("newchild"));
        Assert.assertNotNull(change);

        final List<VcsException> exceptions = new ArrayList<VcsException>();
        SvnVcs.getInstance(myProject).getRollbackEnvironment().rollbackChanges(Collections.singletonList(change), exceptions,
                                                                               RollbackProgressListener.EMPTY);
        Assert.assertTrue(exceptions.isEmpty());
        Assert.assertFalse(new File(myWorkingCopyDir.getPath(), "newchild").exists());
        Assert.assertTrue(new File(myWorkingCopyDir.getPath(), "child").exists());
      }
    });
  }

  // todo undo; undo after commit
  // IDEADEV-7697
  @Test
  public void testMovePackageToParent() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile child = createDirInCommand(myWorkingCopyDir, "child");
    final VirtualFile grandChild = createDirInCommand(child, "grandChild");
    createFileInCommand(grandChild, "a.txt", "a");
    checkin();
    final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject);
    insideInitializedChangeListManager(changeListManager, new Runnable() {
      @Override
      public void run() {
        moveFileInCommand(grandChild, myWorkingCopyDir);
        refreshVfs();   // wait for end of refresh operations initiated from SvnFileSystemListener
        changeListManager.ensureUpToDate(false);
        final List<Change> changes = new ArrayList<Change>(changeListManager.getDefaultChangeList().getChanges());
        Assert.assertEquals(listToString(changes), 2, changes.size());
        sortChanges(changes);
        verifyChange(changes.get(0), "child" + File.separatorChar + "grandChild", "grandChild");
        verifyChange(changes.get(1), "child" + File.separatorChar + "grandChild" + File.separatorChar + "a.txt",
                     "grandChild" + File.separatorChar + "a.txt");
      }
    });
  }

  private String listToString(final List<Change> changes) {
    return "{" + StringUtil.join(changes, StringUtil.createToStringFunction(Change.class), ",") + "}";
  }

  // IDEADEV-19223
  @Test
  public void testRollbackRenameWithUnversioned() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile child = createDirInCommand(myWorkingCopyDir, "child");
    createFileInCommand(child, "a.txt", "a");
    checkin();
    disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile unversioned = createFileInCommand(child, "u.txt", "u");
    final VirtualFile unversionedDir = createDirInCommand(child, "uc");
    createFileInCommand(unversionedDir, "c.txt", "c");

    final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject);
    insideInitializedChangeListManager(changeListManager, new Runnable() {
      @Override
      public void run() {
        changeListManager.ensureUpToDate(false);
        Assert.assertEquals(FileStatus.UNKNOWN, changeListManager.getStatus(unversioned));

        renameFileInCommand(child, "newchild");
        File childPath = new File(myWorkingCopyDir.getPath(), "child");
        File newChildPath = new File(myWorkingCopyDir.getPath(), "newchild");
        Assert.assertTrue(new File(newChildPath, "a.txt").exists());
        Assert.assertTrue(new File(newChildPath, "u.txt").exists());
        Assert.assertFalse(new File(childPath, "u.txt").exists());

        refreshVfs();
        changeListManager.ensureUpToDate(false);
        final List<Change> changes = new ArrayList<Change>();
        changes.add(ChangeListManager.getInstance(myProject).getChange(myWorkingCopyDir.findChild("newchild").findChild("a.txt")));
        changes.add(ChangeListManager.getInstance(myProject).getChange(myWorkingCopyDir.findChild("newchild")));

        final List<VcsException> exceptions = new ArrayList<VcsException>();
        SvnVcs.getInstance(myProject).getRollbackEnvironment().rollbackChanges(changes, exceptions, RollbackProgressListener.EMPTY);
        try {
          Thread.sleep(300);
        }
        catch (InterruptedException e) {
          //
        }
        Assert.assertTrue(exceptions.isEmpty());
        final File fileA = new File(childPath, "a.txt");
        Assert.assertTrue(fileA.getAbsolutePath(), fileA.exists());
        final File fileU = new File(childPath, "u.txt");
        Assert.assertTrue(fileU.getAbsolutePath(), fileU.exists());
        final File unversionedDirFile = new File(childPath, "uc");
        Assert.assertTrue(unversionedDirFile.exists());
        Assert.assertTrue(new File(unversionedDirFile, "c.txt").exists());
      }
    });
  }

  // IDEA-13824
  @Test
  public void testRenameFileRenameDir() throws Exception {
    setNativeAcceleration(true);  //todo debug
    final VirtualFile child = prepareDirectoriesForRename();
    final VirtualFile f = child.findChild("a.txt");
    renameFileInCommand(f, "anew.txt");
    renameFileInCommand(child, "newchild");

    verifySorted(runSvn("status"), "A + newchild", "A + newchild" + File.separatorChar + "anew.txt",
                 "D child", "D child" + File.separatorChar + "a.txt", "D child" + File.separatorChar + "grandChild", "D child" + File.separatorChar + "grandChild" + File.separatorChar + "b.txt", "D + newchild" + File.separatorChar + "a.txt");

    final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject);
    insideInitializedChangeListManager(changeListManager, new Runnable() {
      @Override
      public void run() {
        refreshVfs();   // wait for end of refresh operations initiated from SvnFileSystemListener
        changeListManager.ensureUpToDate(false);
        final List<Change> changes = new ArrayList<Change>(changeListManager.getDefaultChangeList().getChanges());
        final List<VcsException> list = SvnVcs.getInstance(myProject).getCheckinEnvironment().commit(changes, "test");
        Assert.assertEquals(0, list.size());
      }
    });
  }

  // IDEADEV-19364
  @Test
  public void testUndoMovePackage() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile parent1 = createDirInCommand(myWorkingCopyDir, "parent1");
    final VirtualFile parent2 = createDirInCommand(myWorkingCopyDir, "parent2");
    final VirtualFile child = createDirInCommand(parent1, "child");
    createFileInCommand(child, "a.txt", "a");
    checkin();

    moveFileInCommand(child, parent2);
    undo();
    final File childPath = new File(parent1.getPath(), "child");
    Assert.assertTrue(childPath.exists());
    Assert.assertTrue(new File(childPath, "a.txt").exists());
  }

  // IDEADEV-19552
  @Test
  public void testUndoRename() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A");
    checkin();

    renameFileInCommand(file, "b.txt");
    undo();
    Assert.assertTrue(new File(myWorkingCopyDir.getPath(), "a.txt").exists());
    Assert.assertFalse(new File(myWorkingCopyDir.getPath(), "b.txt").exists());
  }

  @Test
  public void testUndoCommittedRenameFile() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A");
    checkin();

    renameFileInCommand(file, "b.txt");
    checkin();
    undo();
    verifySorted(runSvn("status"), "A + a.txt", "D b.txt");
  }

  // IDEADEV-19336
  @Test
  public void testUndoMoveCommittedPackage() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    enableSilentOperation(VcsConfiguration.StandardConfirmation.REMOVE);
    final VirtualFile parent1 = createDirInCommand(myWorkingCopyDir, "parent1");
    final VirtualFile parent2 = createDirInCommand(myWorkingCopyDir, "parent2");
    final VirtualFile child = createDirInCommand(parent1, "child");
    createFileInCommand(child, "a.txt", "a");
    checkin();

    moveFileInCommand(child, parent2);
    checkin();

    undo();
    verifySorted(runSvn("status"), "A + parent1" + File.separatorChar + "child",
                 "D parent2" + File.separatorChar + "child",
                 "D parent2" + File.separatorChar + "child" + File.separatorChar + "a.txt");
  }

  @Test
  public void testMoveToUnversioned() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A");
    final VirtualFile child = moveToNewPackage(file, "child");
    verifySorted(runSvn("status"), "A child", "A child" + File.separatorChar + "a.txt");
    checkin();
    disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned");
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    verifySorted(runSvn("status"), "? unversioned");

    moveFileInCommand(child, unversioned);
    verifySorted(runSvn("status"), "? unversioned", "D child", "D child" + File.separator + "a.txt");
  }

  @Test
  public void testUndoMoveToUnversioned() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A");
    final VirtualFile child = moveToNewPackage(file, "child");
    verifySorted(runSvn("status"), "A child", "A child" + File.separatorChar + "a.txt");
    checkin();
    disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned");
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    verifySorted(runSvn("status"), "? unversioned");

    moveFileInCommand(child, unversioned);
    verifySorted(runSvn("status"), "? unversioned", "D child", "D child" + File.separator + "a.txt");

    undo();
    verifySorted(runSvn("status"), "? unversioned");
  }

  @Test
  public void testUndoMoveUnversionedToUnversioned() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);

    disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A");
    verifySorted(runSvn("status"), "? a.txt");
    final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned");
    moveFileInCommand(file, unversioned);
    verifySorted(runSvn("status"), "? unversioned");
    undo();
    verifySorted(runSvn("status"), "? a.txt", "? unversioned");
  }

  @Test
  public void testUndoMoveAddedToUnversioned() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);

    final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A");
    verifySorted(runSvn("status"), "A a.txt");
    disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned");
    moveFileInCommand(file, unversioned);
    verifySorted(runSvn("status"), "? unversioned");
    undo();
    verifySorted(runSvn("status"), "? a.txt", "? unversioned");
  }

  @Test
  public void testUndoMoveToUnversionedCommitted() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A");
    final VirtualFile child = moveToNewPackage(file, "child");
    verifySorted(runSvn("status"), "A child", "A child" + File.separatorChar + "a.txt");
    checkin();
    disableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile unversioned = createDirInCommand(myWorkingCopyDir, "unversioned");
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    verifySorted(runSvn("status"), "? unversioned");

    moveFileInCommand(child, unversioned);
    verifySorted(runSvn("status"), "? unversioned", "D child", "D child" + File.separator + "a.txt");
    checkin();

    undo();
    verifySorted(runSvn("status"), "? child", "? unversioned");
  }

  // IDEA-92941
  @Test
  public void testUndoNewMove() throws Exception {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile sink = createDirInCommand(myWorkingCopyDir, "sink");
    final VirtualFile child = createDirInCommand(myWorkingCopyDir, "child");
    verifySorted(runSvn("status"), "A child", "A sink");
    checkin();
    final VirtualFile file = createFileInCommand(child, "a.txt", "A");
    verifySorted(runSvn("status"), "A child" + File.separatorChar + "a.txt");
    moveFileInCommand(file, sink);
    verifySorted(runSvn("status"), "A sink" + File.separatorChar + "a.txt");
    undo();
    verifySorted(runSvn("status"), "A child" + File.separatorChar + "a.txt");
  }

  // todo undo, undo committed?
  @Test
  public void testMoveToNewPackage() throws Throwable {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A");
    moveToNewPackage(file, "child");
    verifySorted(runSvn("status"), "A child", "A child" + File.separatorChar + "a.txt");
  }

  @Test
  public void testMoveToNewPackageCommitted() throws Throwable {
    enableSilentOperation(VcsConfiguration.StandardConfirmation.ADD);
    final VirtualFile file = createFileInCommand(myWorkingCopyDir, "a.txt", "A");
    checkin();
    moveToNewPackage(file, "child");
    verifySorted(runSvn("status"), "A child", "A + child" + File.separatorChar + "a.txt", "D a.txt");
  }

  private VirtualFile moveToNewPackage(final VirtualFile file, final String packageName) throws Exception {
    final VirtualFile[] dir = new VirtualFile[1];
    new WriteCommandAction.Simple(myProject) {
      @Override
      public void run() {
        try {
          dir[0] = myWorkingCopyDir.createChildDirectory(this, packageName);
          file.move(this, dir[0]);
        }
        catch (IOException e) {
          throw new RuntimeException(e);
        }

      }
    }.execute().throwException();
    return dir[0];
  }
}
