/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.tests.ccvs.core.subscriber;

import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.List;

import junit.framework.Test;

import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.*;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.internal.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.core.subscribers.*;
import org.eclipse.team.internal.ui.synchronize.*;
import org.eclipse.team.tests.ccvs.ui.SubscriberParticipantSyncInfoSource;
import org.eclipse.team.ui.synchronize.*;
import org.eclipse.ui.PartInitException;

/**
 * Tests the change set mode of the synchronize view
 */
public class CVSChangeSetTests extends CVSSyncSubscriberTest {

	public static Test suite() {
	    return suite(CVSChangeSetTests.class);
	}
	
	public CVSChangeSetTests() {
		super();
	}
	
	public CVSChangeSetTests(String name) {
		super(name);
	}
	
    private void assertIncomingChangesInSets(IFile[][] files, String[] messages) throws CoreException {
        // Get the workspace subscriber which also creates a participant and page in the sync view
        Subscriber workspaceSubscriber = getWorkspaceSubscriber();
        refresh(workspaceSubscriber);
        ISynchronizeModelElement root = getModelRoot(workspaceSubscriber);
        ChangeSetDiffNode[] nodes = getCheckedInChangeSetNodes(root);
        assertNodesInViewer(workspaceSubscriber, nodes);
        assertEquals("The number of change sets in the sync view do not match the expected number", messages.length, nodes.length);
        for (int i = 0; i < messages.length; i++) {
            String message = messages[i];
            ChangeSetDiffNode node = getCommitSetFor(root, message);
            assertNotNull("The commit set for '" + message + "' is not in the sync view", node);
            List filesInSet = new ArrayList();
            getFileChildren(node, filesInSet);
            assertTrue("The number of files in the set do not match the expected number", files[i].length == filesInSet.size());
            for (int j = 0; j < files[i].length; j++) {
                IFile file = files[i][j];
                assertTrue("File " + file.getFullPath() + " is not in the set", filesInSet.contains(file));
            }
        }
    }

    private void assertNodesInViewer(Subscriber workspaceSubscriber, ChangeSetDiffNode[] nodes) throws PartInitException {
        ISynchronizeParticipant participant = SubscriberParticipantSyncInfoSource.getParticipant(workspaceSubscriber);
        SubscriberParticipantPage page = (SubscriberParticipantPage)SubscriberParticipantSyncInfoSource.getSyncViewPage(participant);
        TreeViewer viewer = (TreeViewer)page.getViewer();
        Tree tree = viewer.getTree();
        List nodeList = new ArrayList();
        nodeList.addAll(Arrays.asList(nodes));
        TreeItem[] items = tree.getItems();
        removeTreeItemsFromList(nodeList, items);
        assertTrue("Not all nodes are visible in the view", nodeList.isEmpty());
    }

    private void removeTreeItemsFromList(List nodeList, TreeItem[] items) {
        for (int i = 0; i < items.length; i++) {
            TreeItem item = items[i];
            nodeList.remove(item.getData());
            TreeItem[] children = item.getItems();
            removeTreeItemsFromList(nodeList, children);
        }
    }

    private ChangeSetDiffNode[] getCheckedInChangeSetNodes(ISynchronizeModelElement root) {
        List result = new ArrayList();
        IDiffElement[] children = root.getChildren();
        for (int i = 0; i < children.length; i++) {
            IDiffElement element = children[i];
            if (element instanceof ChangeSetDiffNode) {
                ChangeSetDiffNode node = (ChangeSetDiffNode)element;
                if (node.getSet() instanceof CheckedInChangeSet) {
                    result.add(node);
                }
            }
        }
        return (ChangeSetDiffNode[]) result.toArray(new ChangeSetDiffNode[result.size()]);
    }
    
    private ChangeSetDiffNode[] getActiveChangeSetNodes(ISynchronizeModelElement root) {
        List result = new ArrayList();
        IDiffElement[] children = root.getChildren();
        for (int i = 0; i < children.length; i++) {
            IDiffElement element = children[i];
            if (element instanceof ChangeSetDiffNode) {
                ChangeSetDiffNode node = (ChangeSetDiffNode)element;
                if (node.getSet() instanceof ActiveChangeSet) {
                    result.add(node);
                }
            }
        }
        return (ChangeSetDiffNode[]) result.toArray(new ChangeSetDiffNode[result.size()]);
    }

    /**
     * Adds IFiles to the list
     */
    private void getFileChildren(ISynchronizeModelElement node, List list) {
        IResource resource = node.getResource();
        if (resource != null && resource.getType() == IResource.FILE) {
            list.add(resource);
        }
        IDiffElement[] children = node.getChildren();
        for (int i = 0; i < children.length; i++) {
            IDiffElement child = children[i];
            getFileChildren((ISynchronizeModelElement)child, list);
        }
        return;
    }

    private ChangeSetDiffNode getCommitSetFor(ISynchronizeModelElement root, String message) {
        IDiffElement[] children = root.getChildren();
        for (int i = 0; i < children.length; i++) {
            IDiffElement element = children[i];
            if (element instanceof ChangeSetDiffNode) {
                ChangeSetDiffNode node = (ChangeSetDiffNode)element;
                if (node.getSet().getComment().equals(message)) {
                    return node;
                }
            }
        }
        return null;
    }

    private void refresh(Subscriber workspaceSubscriber) throws TeamException {
        workspaceSubscriber.refresh(workspaceSubscriber.roots(), IResource.DEPTH_INFINITE, DEFAULT_MONITOR);
    }

    private void enableChangeSets(Subscriber workspaceSubscriber) throws PartInitException {
        ISynchronizeParticipant participant = SubscriberParticipantSyncInfoSource.getParticipant(workspaceSubscriber);
        SubscriberParticipantPage page = (SubscriberParticipantPage)SubscriberParticipantSyncInfoSource.getSyncViewPage(participant);
        ChangeSetModelManager manager = (ChangeSetModelManager)page.getConfiguration().getProperty(SynchronizePageConfiguration.P_MODEL_MANAGER);
        manager.setCommitSetsEnabled(true);
        page.getConfiguration().setMode(ISynchronizePageConfiguration.BOTH_MODE);
    }

    private void enableCheckedInChangeSets(Subscriber workspaceSubscriber) throws PartInitException {
        enableChangeSets(workspaceSubscriber);
        ISynchronizeParticipant participant = SubscriberParticipantSyncInfoSource.getParticipant(workspaceSubscriber);
        SubscriberParticipantPage page = (SubscriberParticipantPage)SubscriberParticipantSyncInfoSource.getSyncViewPage(participant);
        page.getConfiguration().setMode(ISynchronizePageConfiguration.INCOMING_MODE);
    }
    
    private void enableActiveChangeSets(Subscriber workspaceSubscriber) throws PartInitException {
        enableChangeSets(workspaceSubscriber);
        ISynchronizeParticipant participant = SubscriberParticipantSyncInfoSource.getParticipant(workspaceSubscriber);
        SubscriberParticipantPage page = (SubscriberParticipantPage)SubscriberParticipantSyncInfoSource.getSyncViewPage(participant);
        page.getConfiguration().setMode(ISynchronizePageConfiguration.OUTGOING_MODE);
    }
    
    /*
     * Wait until all the background handlers have settled and then return the root element in the sync view
     */
    private ISynchronizeModelElement getModelRoot(Subscriber workspaceSubscriber) throws CoreException {
        IProgressMonitor eventLoopProgressMonitor = new IProgressMonitor() {
			public void beginTask(String name, int totalWork) {
			}
			public void done() {
			}
			public void internalWorked(double work) {
			}
			public boolean isCanceled() {
				return false;
			}
			public void setCanceled(boolean value) {
			}
			public void setTaskName(String name) {
			}
			public void subTask(String name) {
			}
			public void worked(int work) {
				while (Display.getCurrent().readAndDispatch()) {}
			}
		};
        SubscriberParticipantSyncInfoSource.getCollector(workspaceSubscriber);
        ISynchronizeParticipant participant = SubscriberParticipantSyncInfoSource.getParticipant(workspaceSubscriber);
        ChangeSetCapability capability = ((IChangeSetProvider)participant).getChangeSetCapability();
        SubscriberChangeSetManager activeManager = (SubscriberChangeSetManager)capability.getActiveChangeSetManager();
        activeManager.waitUntilDone(eventLoopProgressMonitor);
        SubscriberParticipantPage page = (SubscriberParticipantPage)SubscriberParticipantSyncInfoSource.getSyncViewPage(participant);
        ChangeSetModelManager manager = (ChangeSetModelManager)page.getConfiguration().getProperty(SynchronizePageConfiguration.P_MODEL_MANAGER);
        AbstractSynchronizeModelProvider provider = (AbstractSynchronizeModelProvider)manager.getActiveModelProvider();
        provider.waitUntilDone(eventLoopProgressMonitor);
        return provider.getModelRoot();
    }

    private ActiveChangeSetManager getActiveChangeSetManager() {
        return CVSUIPlugin.getPlugin().getChangeSetManager();
    }
    
    /*
     * Assert that the given resources make up the given set both directly
     * and by what is displayed in the sync view.
     */
    private void assertInActiveSet(IResource[] resources, ActiveChangeSet set) throws CoreException {
        assertResourcesAreTheSame(resources, set.getResources(), true);
        ISynchronizeModelElement root = getModelRoot(((SubscriberChangeSetManager)getActiveChangeSetManager()).getSubscriber());
        ChangeSetDiffNode node = getChangeSetNodeFor(root, set);
        assertNotNull("Change set " + set.getTitle() + " did not appear in the sync view", node);
        IResource[] outOfSync = getOutOfSyncResources(node);
        assertResourcesAreTheSame(resources, outOfSync, true);
        // Assert that all active sets are visible in the view
        ChangeSet[] sets = getActiveChangeSetManager().getSets();
        for (int i = 0; i < sets.length; i++) {
            ChangeSet changeSet = sets[i];
            node = getChangeSetNodeFor(root, changeSet);
            assertNotNull("The node for set " + set.getName() + " is not in the view", node);
            
        }
        ChangeSetDiffNode[] nodes = getActiveChangeSetNodes(root);
        assertNodesInViewer(getWorkspaceSubscriber(), nodes);
    }
    
    private ChangeSetDiffNode getChangeSetNodeFor(ISynchronizeModelElement root, ChangeSet set) {
        IDiffElement[] children = root.getChildren();
        for (int i = 0; i < children.length; i++) {
            IDiffElement element = children[i];
            if (element instanceof ChangeSetDiffNode) {
                ChangeSetDiffNode node = (ChangeSetDiffNode)element;
                if (node.getSet() == set) {
                    return node;
                }
            }
        }
        return null;
    }

    private IResource[] getOutOfSyncResources(ISynchronizeModelElement element) {
        ArrayList arrayList = new ArrayList();
        getOutOfSync(element, arrayList);
        SyncInfo[] infos = (SyncInfo[]) arrayList.toArray(new SyncInfo[arrayList.size()]);
        IResource[] resources = getResources(infos);
        return resources;
    }

    private IResource[] getResources(SyncInfo[] infos) {
        IResource[] resources = new IResource[infos.length];
        for (int i = 0; i < resources.length; i++) {
            resources[i] = infos[i].getLocal();
        }
        return resources;
    }

    private void getOutOfSync(ISynchronizeModelElement node, List list) {
        SyncInfo info = getSyncInfo(node);
        if (info != null && info.getKind() != SyncInfo.IN_SYNC) {
            list.add(info);
        }
        IDiffElement[] children = node.getChildren();
        for (int i = 0; i < children.length; i++) {
            IDiffElement child = children[i];
            getOutOfSync((ISynchronizeModelElement)child, list);
        }
        return;
    }
    
    private SyncInfo getSyncInfo(ISynchronizeModelElement node) {
        if (node instanceof IAdaptable) {
            return (SyncInfo)((IAdaptable)node).getAdapter(SyncInfo.class);
        }
        return null;
    }

    private void assertResourcesAreTheSame(IResource[] resources1, IResource[] resources2, boolean doNotAllowExtra) {
        if (doNotAllowExtra) {
            if (resources1.length != resources2.length) {
	            System.out.println("Expected");
	            for (int i = 0; i < resources1.length; i++) {
	                IResource resource = resources1[i];
	                System.out.println(resource.getFullPath().toString());
	            }
	            System.out.println("Actual");
	            for (int i = 0; i < resources2.length; i++) {
	                IResource resource = resources2[i];
	                System.out.println(resource.getFullPath().toString());
	            }
	        }
	        assertEquals("The number of resources do not match the expected number", resources1.length, resources2.length);
        }
        for (int i = 0; i < resources1.length; i++) {
            IResource resource = resources1[i];
            boolean found = false;
            for (int j = 0; j < resources2.length; j++) {
                IResource resource2 = resources2[j];
                if (resource2.equals(resource)) {
                    found = true;
                    break;
                }
            }
            assertTrue("Expected resource " + resource.getFullPath().toString() + " was not present", found);
        }
    }

    /*
     * Assert that the given resources make up the root set
     * displayed in the sync view. The root set is those 
     * resources that are not part of an active change set.
     */
    private void assertInRootSet(IResource[] resources) throws CoreException {
        ISynchronizeModelElement[] nodes = getNonChangeSetRoots(getModelRoot(((SubscriberChangeSetManager)getActiveChangeSetManager()).getSubscriber()));
        List list = new ArrayList();
        for (int i = 0; i < nodes.length; i++) {
            ISynchronizeModelElement element = nodes[i];
            getOutOfSync(element, list);
        }
        IResource[] outOfSync = getResources((SyncInfo[]) list.toArray(new SyncInfo[list.size()]));
        // Only require that the expected resources are there but allow extra.
        // This is required because of junk left over from previous tests.
        // This means there is a bug somewhere. But where?
        assertResourcesAreTheSame(resources, outOfSync, false /* allow extra out-of-sync resources */);
        
    }
    
    private ISynchronizeModelElement[] getNonChangeSetRoots(ISynchronizeModelElement modelRoot) {
        List result = new ArrayList();
        IDiffElement[] children = modelRoot.getChildren();
        for (int i = 0; i < children.length; i++) {
            IDiffElement element = children[i];
            if (!(element instanceof ChangeSetDiffNode)) {
                result.add(element);
            }
        }
        return (ISynchronizeModelElement[]) result.toArray(new ISynchronizeModelElement[result.size()]);
    }

    public void testSimpleCommit() throws CoreException {
        enableCheckedInChangeSets(getWorkspaceSubscriber());
        
	    IProject project = createProject(new String[] { "file1.txt", "file2.txt", "folder1/", "folder1/a.txt", "folder1/b.txt"});
	    
	    // Modify a file in a copy
	    IProject copy = checkoutCopy(project, CVSTag.DEFAULT);
	    setContentsAndEnsureModified(copy.getFile("file1.txt"));
	    String message1 = "Commit 1";
	    commitResources(new IResource[] {copy}, IResource.DEPTH_INFINITE, message1);
	    assertIncomingChangesInSets(new IFile[][] {{ project.getFile("file1.txt") }}, new String[] {message1});
	    
	    // Modify the copy some more
	    setContentsAndEnsureModified(copy.getFile("file2.txt"));
	    setContentsAndEnsureModified(copy.getFile("folder1/a.txt"));
	    String message2 = "Commit 2";
	    commitResources(new IResource[] {copy}, IResource.DEPTH_INFINITE, message2);
	    assertIncomingChangesInSets(new IFile[][] {
	            { project.getFile("file1.txt") },
	            { project.getFile("file2.txt"), project.getFile("folder1/a.txt") }
	            }, new String[] {message1, message2});
	    
	    // Modify the copy some more
	    setContentsAndEnsureModified(copy.getFile("file2.txt"));
	    String message3 = "Commit 3";
	    commitResources(new IResource[] {copy}, IResource.DEPTH_INFINITE, message3);
	    assertIncomingChangesInSets(new IFile[][] {
	            { project.getFile("file1.txt") },
	            { project.getFile("folder1/a.txt") },
	            { project.getFile("file2.txt")}
	            }, new String[] {message1, message2, message3});
	    
	    // Now commit the files in one of the sets and ensure it is removed from the view
	    updateResources(new IResource[] { project.getFile("file1.txt")}, false);
	    assertIncomingChangesInSets(new IFile[][] {
	            { project.getFile("folder1/a.txt") },
	            { project.getFile("file2.txt")}
	            }, new String[] {message2, message3});
	}
	
    public void testSimpleActiveChangeSet() throws CoreException {
        IProject project = createProject(new String[] { "file1.txt", "file2.txt", "folder1/", "folder1/a.txt", "folder1/b.txt"});
        // Enable Change Sets
        enableActiveChangeSets(getWorkspaceSubscriber());
	    // Add a folder and file
	    IFolder newFolder = project.getFolder("folder2");
        newFolder.create(false, true, null);
        IFile newFile = newFolder.getFile("file.txt");
        newFile.create(new ByteArrayInputStream("Hi There".getBytes()), false, null);
        // Create an active commit set and assert that it appears in the sync view
        ActiveChangeSetManager manager = getActiveChangeSetManager();
        ActiveChangeSet set = manager.createSet("test", new IDiff[0]);
        manager.add(set);
        assertInActiveSet(new IResource[] { }, set);
        assertInRootSet(new IResource[] {newFolder, newFile});
        // Add the new file to the set and assert that the file is in the set and the folder is still at the root
        set.add(new IResource[] { newFile });
        assertInActiveSet(new IResource[] { newFile }, set);
        assertInRootSet(new IResource[] {newFolder });
	    // Add the folder to the set
        set.add(new IResource[] { newFolder });
        assertInActiveSet(new IResource[] { newFolder, newFile }, set);
    }
}
