package test.org.seasar.dao.impl;

import org.seasar.dao.BeanMetaData;
import org.seasar.dao.PrimaryKeyNotFoundRuntimeException;
import org.seasar.dao.RelationPropertyType;
import org.seasar.dao.impl.BeanMetaDataImpl;
import org.seasar.dao.unit.S2DaoTestCase;
import org.seasar.extension.jdbc.PropertyType;

/**
 * @author higa
 *
 */
public class BeanMetaDataImplTest extends S2DaoTestCase {
	
	/**
	 * Constructor for InvocationImplTest.
	 * @param arg0
	 */
	public BeanMetaDataImplTest(String arg0) {
		super(arg0);
	}

	public static void main(String[] args) {
		junit.textui.TestRunner.run(BeanMetaDataImplTest.class);
	}
	
	protected void setUp() throws Exception {
		include("j2ee.dicon");
	}

	public void testSetup() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(MyBean.class, getDatabaseMetaData(), getDbms());
		assertEquals("1", "MyBean", bmd.getTableName());
		assertEquals("2", 3, bmd.getPropertyTypeSize());
		PropertyType aaa = bmd.getPropertyType("aaa");
		assertEquals("3", "aaa", aaa.getColumnName());
		PropertyType bbb = bmd.getPropertyType("bbb");
		assertEquals("4", "myBbb", bbb.getColumnName());
		assertEquals("5", 1, bmd.getRelationPropertyTypeSize());
		RelationPropertyType rpt = bmd.getRelationPropertyType(0);
		assertEquals("6", 1, rpt.getKeySize());
		assertEquals("7", "ddd", rpt.getMyKey(0));
		assertEquals("8", "id", rpt.getYourKey(0));
		assertNotNull("9", bmd.getIdentifierGenerator());
		assertEquals("10", 1, bmd.getPrimaryKeySize());
		assertEquals("11", "aaa", bmd.getPrimaryKey(0));
	}
	
	public void testSetupDatabaseMetaData() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Employee.class, getDatabaseMetaData(), getDbms());
		PropertyType empno = bmd.getPropertyType("empno");
		assertEquals("1", true, empno.isPrimaryKey());
		assertEquals("2", true, empno.isPersistent());
		PropertyType ename = bmd.getPropertyType("ename");
		assertEquals("3", false, ename.isPrimaryKey());
		PropertyType dummy = bmd.getPropertyType("dummy");
		assertEquals("4", false, dummy.isPersistent());
	}
	
	public void testSetupAutoInsertSql() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Employee.class, getDatabaseMetaData(), getDbms());
		System.out.println(bmd.getAutoInsertSql());
	}
	
	public void testSetupAutoUpdateSql() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Department.class, getDatabaseMetaData(), getDbms());
		BeanMetaData bmd2 = new BeanMetaDataImpl(Employee.class, getDatabaseMetaData(), getDbms());
		System.out.println(bmd.getAutoUpdateSql());
		System.out.println(bmd2.getAutoUpdateSql());
	}
	
	public void testSetupAutoUpdateSql2() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Fff.class, getDatabaseMetaData(), getDbms());
		try {
			bmd.getAutoUpdateSql();
			fail();
		} catch (PrimaryKeyNotFoundRuntimeException ex) {
			System.out.println(ex);
		}
	}
	
	public void testSetupAutoDeleteSql() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Department.class, getDatabaseMetaData(), getDbms());
		BeanMetaData bmd2 = new BeanMetaDataImpl(Employee.class, getDatabaseMetaData(), getDbms());
		System.out.println(bmd.getAutoDeleteSql());
		System.out.println(bmd2.getAutoDeleteSql());
	}
	
	public void testSetupAutoDeleteSql2() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Fff.class, getDatabaseMetaData(), getDbms());
		try {
			bmd.getAutoDeleteSql();
			fail();
		} catch (PrimaryKeyNotFoundRuntimeException ex) {
			System.out.println(ex);
		}
	}
	
	public void testSetupAutoSelectList() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Department.class, getDatabaseMetaData(), getDbms());
		BeanMetaData bmd2 = new BeanMetaDataImpl(Employee.class, getDatabaseMetaData(), getDbms());
		String sql = bmd.getAutoSelectList();
		String sql2 = bmd2.getAutoSelectList();
		System.out.println(sql);
		System.out.println(sql2);
		
		assertTrue("1", sql2.indexOf("EMP.deptno") > 0);
		assertTrue("2", sql2.indexOf("department.deptno AS deptno_0") > 0);
		assertTrue("3", sql2.indexOf("dummy_0") < 0);
	}
	
	public void testConvertFullColumnName() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Employee.class, getDatabaseMetaData(), getDbms());
		assertEquals("1", "EMP.empno", bmd.convertFullColumnName("empno"));
		assertEquals("2", "department.dname", bmd.convertFullColumnName("dname_0"));
	}
	
	public void testHasPropertyTypeByAliasName() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Employee.class, getDatabaseMetaData(), getDbms());
		assertEquals("1", true, bmd.hasPropertyTypeByAliasName("empno"));
		assertEquals("2", true, bmd.hasPropertyTypeByAliasName("dname_0"));
		assertEquals("3", false, bmd.hasPropertyTypeByAliasName("xxx"));
		assertEquals("4", false, bmd.hasPropertyTypeByAliasName("xxx_10"));
		assertEquals("5", false, bmd.hasPropertyTypeByAliasName("xxx_0"));
	}
	
	public void testGetPropertyTypeByAliasName() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Employee.class, getDatabaseMetaData(), getDbms());
		assertNotNull("1", bmd.getPropertyTypeByAliasName("empno"));
		assertNotNull("2", bmd.getPropertyTypeByAliasName("dname_0"));
	}
	
	public void testSelfReference() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Employee4.class, getDatabaseMetaData(), getDbms());
		RelationPropertyType rpt = bmd.getRelationPropertyType("parent");
		assertEquals("1", Employee4.class, rpt.getBeanMetaData().getBeanClass());
	}
	
	public void testNoPersistentColumnsEmpty() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Ddd.class, getDatabaseMetaData(), getDbms());
		PropertyType pt = bmd.getPropertyType("name");
		assertEquals("1", true, pt.isPersistent());
	}
	
	public void testNoPersistentColumnsDefined() throws Exception {
		BeanMetaData bmd = new BeanMetaDataImpl(Eee.class, getDatabaseMetaData(), getDbms());
		PropertyType pt = bmd.getPropertyType("name");
		assertEquals("1", false, pt.isPersistent());
	}
	
	public static class MyBean {
		public static final String TABLE = "MyBean";
		public static final String aaa_ID = "assigned";
		public static final String bbb_COLUMN = "myBbb";
		public static final int ccc_RELNO = 0;
		public static final String ccc_RELKEYS = "ddd:id";
		
		private Integer aaa_;
		private String bbb_;
		private Ccc ccc_;
		private Integer ddd_;
		
		public Integer getAaa() {
			return aaa_;
		}
		
		public void setAaa(Integer aaa) {
			aaa_ = aaa;
		}
		
		public String getBbb() {
			return bbb_;
		}
		
		public void setBbb(String bbb) {
			bbb_ = bbb;
		}
		
		public Ccc getCcc() {
			return ccc_;
		}
		
		public void setCcc(Ccc ccc) {
			ccc_ = ccc;
		}
		
		public Integer getDdd() {
			return ddd_;
		}
		
		public void setDdd(Integer ddd) {
			ddd_ = ddd;
		}
	}
	
	public static class Ccc {
		public static final String id_ID = "assigned";
		private Integer id_;
		public Integer getId() {
			return id_;
		}
		public void setId(Integer id) {
			id_ = id;
		}
	}
	
	public static class Ddd extends Ccc {
		public static final String NO_PERSISTENT_COLUMNS = "";
		private String name_;
		public String getName() {
			return name_;
		}
		public void setName(String name) {
			name_ = name;
		}
	}
	
	public static class Eee extends Ccc {
		public static final String NO_PERSISTENT_COLUMNS = "name";
		private String name_;
		public String getName() {
			return name_;
		}
		public void setName(String name) {
			name_ = name;
		}
	}
	
	public static class Fff {
		private Integer id_;
		public Integer getId() {
			return id_;
		}
		public void setId(Integer id) {
			id_ = id;
		}
	}
}