/*
 * Created on Mar 4, 2005
 */
package org.bodington.server.resources;

import java.util.Vector;

import org.bodington.server.BuildingContext;
import org.bodington.server.BuildingServerException;
import org.bodington.server.BuildingServerTest;

/**
 * @author buckett
 */
public class ResourceTreeTest extends BuildingServerTest {

	/*
	 * @see BuildingServerTest#setUp()
	 */
	ResourceTree resourceTree;

	protected void setUp() throws Exception {
		super.setUp();
		BuildingContext.getContext().setUser(user);
		resource.delete();
		resourceTree = ResourceTreeManager.getInstance();
		resource = new Resource("site", "title", "description", "introduction");
		resourceTree.addResource(null, resource);        
	}

	public void testGetInstance() throws BuildingServerException {
		assertTrue(ResourceTreeManager.getInstance() != null);
	}

	/*
	 * Class under test for Resource findResource(String)
	 */
	public void testFindResourceString() throws BuildingServerException {
        assertNotNull(resourceTree.findResource("/"));
		assertTrue(resourceTree.findResource("/").equals(resource));
		assertEquals(null, resourceTree.findResource("/doesnotexist/here"));
	}

	/*
	 * Class under test for Resource findResource(String[])
	 */
	public void testFindResourceStringArray() throws Exception {
        assertNotNull(resourceTree.findResource(new String[]{}));
		assertTrue(resourceTree.findResource(new String[]{}).equals(resource));

	}

	public void testCountDescendents() throws BuildingServerException {
		assertEquals(0, resourceTree.countDescendents(resource.getPrimaryKey()));
		resourceTree.addResource(resource, new Resource("a", "a", "a", "a"));
		assertEquals(1, resourceTree.countDescendents(resource.getPrimaryKey()));
	}

	public void testLoadResources() {
	}

	public void testMoveResource() throws BuildingServerException {
		Resource child1 = new Resource("child1", "child", "child", "child");
		Resource child2 = new Resource("child2", "child", "child", "child");
		resourceTree.addResource(resource, child1);
		resourceTree.addResource(resource, child2);
		resourceTree.moveResource(child1, child2);
		assertTrue(resourceTree.isInside(child2, child1));
		try {
			resourceTree.moveResource(child2, resource);
			fail("You shouldn't be able to move the root resource");
		} catch (BuildingServerException bse) {
			assertTrue(resourceTree.isInside(child2, resource));
		}
		try {
			resourceTree.moveResource(child2, child1);
			fail("You shouldn't be able to move a resource to a location inside");
		} catch (BuildingServerException bse) {
			assertTrue(resourceTree.isInside(child2, resource));
		}
	}

	public void testSortResources() throws BuildingServerException {
		// We have to clone the children before passing it to the
		// sortResources() method as the parameter is just directly
		// stored in the ResoureTree class.
		Resource child1 = new Resource("1", "1", "1", "1");
		Resource child2 = new Resource("2", "2", "2", "2");
		Resource child3 = new Resource("3", "3", "3", "3");
		resourceTree.addResource(resource, child1);
		resourceTree.addResource(resource, child2);
		resourceTree.addResource(resource, child3);
		Vector children = resource.getChildIds();
		assertTrue(children.get(0).equals(child1.getPrimaryKey()));
		assertTrue(children.get(1).equals(child2.getPrimaryKey()));
		assertTrue(children.get(2).equals(child3.getPrimaryKey()));

		// Swap the first two elements
		children.set(0, child2.getPrimaryKey());
		children.set(1, child1.getPrimaryKey());

		resourceTree.sortResources(resource, (Vector) children.clone());
		assertTrue(resource.getChildIds().equals(children));

		// The same entry apears twice?
		children.set(1, child1.getPrimaryKey());

		resourceTree.sortResources(resource, (Vector) children.clone());
		assertTrue(resource.getChildIds().equals(children));

		// Smaller set.
		children.remove(2);
		try {
			resourceTree.sortResources(resource, (Vector) children.clone());
			fail("You shouldn't be allowed to have less items in the set and children");
		} catch (BuildingServerException bse) {
			assertTrue(true);
		}

	}

	public void testAddResource() throws BuildingServerException {
		// Test adding loads of resources.
		Resource child, parent = resource;
		for (int count = 0; count < 50; count++) {
			child = new Resource("name", "title", "description", "introduction");
			resourceTree.addResource(parent, child);
			parent = child;
		}
		int descendents = resourceTree.countDescendents(resource
				.getPrimaryKey());
		assertEquals(50, descendents);
		Resource newRoot = new Resource("name", "title", "description",
				"introduction");
		resourceTree.addResource(null, newRoot);
		assertTrue(resourceTree.findRootResource().equals(newRoot));
		
		resourceTree.addResource(newRoot, new Resource("name", "title",
            "description", "introduction"));
		
		try {
		    resourceTree.addResource(newRoot, new Resource("name", "title",
	            "description", "introduction"));
		    fail("We shouldn't be able to add two resources with the same name");
		} catch (BuildingServerException bse) {
		    assertEquals(1, newRoot.getChildIds().size());
		}

	}

	public void testRemoveResource() throws BuildingServerException {
		Resource child = new Resource("child", "child", "child", "child");
		resourceTree.addResource(resource, child);
		assertEquals(1, resourceTree.countDescendents(resource.getPrimaryKey()));
		assertEquals(1, resource.getChildIds().size());
		resourceTree.removeResource(child);
		// Can't count the descendents as the remove method doesn't tidy up the
		// resourcetree.
		assertTrue(resource.getChildIds().size() == 0);

	}

	public void testFindRootResource() throws BuildingServerException {
		assertTrue(resourceTree.findRootResource().equals(resource));
	}

	public void testIsInside() throws BuildingServerException {
		Resource child1 = new Resource("child1", "child", "child", "child");
		Resource child2 = new Resource("child2", "child", "child", "child");
		resourceTree.addResource(resource, child1);
		resourceTree.addResource(resource, child2);
		assertTrue(resourceTree.isInside(child1, resource));
		assertFalse(resourceTree.isInside(child1, child2));
	}
    
    public void testfindResourcePert() throws BuildingServerException {
        Resource root = resourceTree.findRootResource();
        
        String name = "/";
        Resource current, next;
        current = root;
        for ( int count = 0; count < 20; count++)
        {
            next = new Resource("a","a","a","a");
            resourceTree.addResource(current, next);
            name = name + "a/";
            current = next;
        }
        for (int count = 0; count < 100; count++)
            assertNotNull(resourceTree.findResource(name));
    }

}