/* ======================================================================
   Parts Copyright 2006 University of Leeds, Oxford University, University of the Highlands and Islands.

   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.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));
    }

}
