/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.openjpa.persistence.jdbc.mapping;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.openjpa.persistence.jdbc.common.apps.mappingApp.*;
import org.apache.openjpa.persistence.common.utils.*;
import junit.framework.*;


public class TestCompositeIdTraversalInSQLMapping extends AbstractTestCase 
{
	
	
	public TestCompositeIdTraversalInSQLMapping(String name)
	{
		super(name, "jdbccactusapp");
	}

	
	public void setUp()
	{
		deleteAll(OwnerOfEntityWithCompositeId.class);
		deleteAll(EntityWithCompositeId.class);
	}
	private void persist(Integer uniqueId, String uniqueName, String relName)
	{
		OwnerOfEntityWithCompositeId owner = new OwnerOfEntityWithCompositeId();
		EntityWithCompositeId relative = new EntityWithCompositeId();
		owner.setName(uniqueName);
		relative.setId(uniqueId);
		relative.setName(relName);
		relative.setValue("foo");
		owner.setRelation(relative);
		
		EntityManager em = currentEntityManager();
		startTx(em);
		em.persist(owner);
		endTx(em);
		endEm(em);
	}
	public void testTraversalWhenSQLSelectsBothEndOfTheRelation ()
	{
		EntityManager em = currentEntityManager();
		Integer uid  = new Integer((int) (System.currentTimeMillis()%100000));
		String uName = "P"+uid;
		String rName = "R"+uName;
		
		persist(uid, uName, rName);
		
		String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID as REL_ID," +
		             "a.RELATION_NAME as REL_NAME, b.ID as C_ID," +
					 "b.NAME as C_NAME, b.VALUE as C_VALUE " +
		             "FROM OWNER_OF_COMPOSITE_ID a, COMPOSITE_ID b " +
		             "WHERE a.RELATION_ID=b.ID AND a.RELATION_NAME=b.NAME " +
		             "AND a.NAME='" + uName + "'";
		
		Query query = em.createNativeQuery(sql, 
			"SQLSelectsBothEndOfTheRelation");
		
		List result = query.getResultList();
		
		assertEquals(1,result.size());
		Object object = result.get(0);
		assertEquals(Object[].class, object.getClass());
		Object[] array = (Object[])object;
		assertEquals(2,array.length);
		assertEquals(OwnerOfEntityWithCompositeId.class,array[0].getClass());
		assertEquals(EntityWithCompositeId.class,array[1].getClass());
		
		OwnerOfEntityWithCompositeId owner = (OwnerOfEntityWithCompositeId)
			array[0];
		
		EntityWithCompositeId relative = (EntityWithCompositeId)array[1];
		
		assertEquals(uName, owner.getName());
		assertEquals(owner.getRelation(), relative);
		assertEquals(relative.getId(),uid);
		assertEquals(relative.getName(), rName);
		assertEquals("foo", relative.getValue());
		endEm(em);
	}

	public void testTraversalWhenSQLSelectsOnlyOneEndOfTheRelation ()
	{
		EntityManager em = currentEntityManager();
		Integer uid  = new Integer((int) (System.currentTimeMillis()%100000));
		String uName = "P"+uid;
		String rName = "R"+uName;
		
		persist (uid, uName, rName);
		String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID as REL_ID," +
		             "a.RELATION_NAME as REL_NAME "+
		             "FROM OWNER_OF_COMPOSITE_ID a " +
		             "WHERE  a.NAME='" + uName + "'";
		
		Query query = em.createNativeQuery(sql, 
			"SQLSelectsOnlyOneEndOfTheRelation");
		
		List result = query.getResultList();
		
		assertEquals(1,result.size());
		Object object = result.get(0);
		assertEquals(OwnerOfEntityWithCompositeId.class,object.getClass());
		
		OwnerOfEntityWithCompositeId owner = (OwnerOfEntityWithCompositeId)
			object;
		
		EntityWithCompositeId relative = owner.getRelation();
		
		assertEquals(uName, owner.getName());
		assertEquals(relative.getId(),uid);
		assertEquals(relative.getName(), rName);
		assertEquals("foo", relative.getValue());
		endEm(em);
	}
	public void testTraversalWhenSQLSelectsUnrelatedInstances ()
	{
		EntityManager em = currentEntityManager();
		Integer uid1  = new Integer((int) (System.currentTimeMillis()%100000));
		Integer uid2  = new Integer(uid1.intValue()+1);
		String uName1 = "P"+uid1;
		String rName1 = "R"+uName1;
		String uName2 = "P"+uid2;
		String rName2 = "R"+uName2;
		
		persist(uid1, uName1, rName1);
		persist(uid2, uName2, rName2);
		
		String sql = "SELECT a.NAME as OWNER_NAME, a.RELATION_ID AS REL_ID," +
        "a.RELATION_NAME AS REL_NAME, " +
        "b.ID AS C_ID, b.NAME AS C_NAME, b.VALUE AS C_VALUE "+
        "FROM OWNER_OF_COMPOSITE_ID a, COMPOSITE_ID b " +
        "WHERE b.NAME='"+ rName2 +"' " +
        "AND a.NAME='" + uName1 + "'";
		
		Query query = em.createNativeQuery(sql, 
				"SQLSelectsUnrelatedInstances");
		
		List result = query.getResultList();
		
		assertEquals(1,result.size());
		Object object = result.get(0);
		assertEquals(Object[].class, object.getClass());
		Object[] array = (Object[])object;
		assertEquals(2,array.length);
		assertEquals(OwnerOfEntityWithCompositeId.class,array[0].getClass());
		assertEquals(EntityWithCompositeId.class,array[1].getClass());
		
		OwnerOfEntityWithCompositeId owner1 = (OwnerOfEntityWithCompositeId)
			array[0];
		EntityWithCompositeId relative1 = owner1.getRelation();
		
		EntityWithCompositeId relative2 = (EntityWithCompositeId)array[1];
		
		assertEquals(uName1, owner1.getName());
		assertEquals(uid1, relative1.getId());
		assertEquals(rName1, relative1.getName());
		assertEquals(uid2, relative2.getId());
		assertEquals(rName2, relative2.getName());
		endEm(em); 
	}
	
	public void testRecursiveTraversal () 
	{
		Integer rootId  = new Integer((int)(System.currentTimeMillis()%100000));
		
		int depth = 3;
		persistChainedRelative(rootId, depth);
		
		String sql = createSelfJoinSQL("RECURSIVE_ENTITY",
				depth,rootId);
		
		EntityManager em = currentEntityManager();
		Query query = em.createNativeQuery(sql, "SQLSelectsChainedRelation");

		List result = query.getResultList();
		
		assertEquals(1, result.size());
		assertEquals(RecursiveEntityWithCompositeId.class,
				result.get(0).getClass());
		
		RecursiveEntityWithCompositeId root = (RecursiveEntityWithCompositeId)
												result.get(0);
		assertEquals(rootId,root.getId());
		assertEquals("P"+rootId,root.getName());
		for (int i=1; i<depth;i++){
			RecursiveEntityWithCompositeId relative = root.getRelation();
			Integer expecetedId = root.getId()+1;
			assertEquals (expecetedId,relative.getId());
			assertEquals ("P"+expecetedId, relative.getName());
			root = relative;
		}
		 
	}
	
	void persistChainedRelative(Integer rootId, int depth)
	{
		RecursiveEntityWithCompositeId root = 
			new RecursiveEntityWithCompositeId();
		root.setId(rootId);
		root.setName("P"+rootId);
		RecursiveEntityWithCompositeId head = root;
		for (int i=1; i<=depth; i++)
		{
			RecursiveEntityWithCompositeId relation = 
				new RecursiveEntityWithCompositeId();
			relation.setId(rootId+i);
			relation.setName("P"+(rootId+i));
			head.setRelation(relation);
			head = relation;
		}
		EntityManager em = currentEntityManager();
		startTx(em);
		em.persist(root);
		endTx(em);
		endEm(em);
	}
	
	String createSelfJoinSQL(String table, int depth, int id)
	{
		
		StringBuffer sql = new StringBuffer("SELECT ");
		for (int i=0; i<depth; i++)
			sql.append("t"+i+".ID AS T"+i+"_ID, ")
			   .append("t"+i+".NAME AS T"+i+"_NAME, ")
			   .append("t"+i+".RELATION_ID AS T"+i+"_REL_ID, ")
			   .append("t"+i+".RELATION_NAME AS T"+i+"_REL_NAME")
			   .append((i==(depth-1))?" " : ", ");
		
		sql.append(" FROM ");
		for (int i=0; i<depth; i++)
			sql.append(table + " t"+i)
			   .append((i==(depth-1))?" " : ", ");
		
		sql.append(" WHERE ");
		for (int i=0; i<(depth-1); i++)
			sql.append("t"+i+".RELATION_ID=t"+(i+1)+".ID AND ")
			   .append("t"+i+".RELATION_NAME=t"+(i+1)+".NAME AND " );
		
		sql.append("t0.ID="+id);
		
		return sql.toString();
	}
}
