/*$Id: SubSchemaDataTestFixture.java 14740 2010-02-03 09:16:34Z jens $*/
/*
 ****************************************************************************
 *                                                                          *
 *                   (c) Copyright 2008 ABM-utvikling                       *
 *                                                                          *
 * This program is free software; you can redistribute it and/or modify it  *
 * under the terms of the GNU General Public License as published by the    *
 * Free Software Foundation; either version 2 of the License, or (at your   *
 * option) any later version.                                               *
 *                                                                          *
 * This program is distributed in the hope that it will be useful, but      *
 * WITHOUT ANY WARRANTY; without even the implied warranty of               *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
 * Public License for more details. http://www.gnu.org/licenses/gpl.html    *
 *                                                                          *
 ****************************************************************************
 */

package no.abmu.questionnaire.domain.fixtures;

import java.util.ArrayList;
import java.util.Collection;

import junit.framework.Assert;
import no.abmu.common.domain.Entity;
import no.abmu.questionnaire.domain.data.FieldData;
import no.abmu.questionnaire.domain.data.SubSchemaData;
import no.abmu.test.domainmodels.AbstractDeepComparator;
import no.abmu.test.domainmodels.DeepCompare;
import no.abmu.test.domainmodels.TestFixture;

import org.hibernate.proxy.HibernateProxyHelper;


/**
 * SubReportDataTestFixture.
 *
 * @author Jens Vindvad, Jens.Vindvad@abm-utvikling.no
 * @author $Author: jens $
 * @version $Rev: 14740 $
 * @date $Date: 2010-02-03 10:16:34 +0100 (Wed, 03 Feb 2010) $
 * @copyright ABM-Utvikling
 *
 */
public class SubSchemaDataTestFixture implements TestFixture {

    public static final DeepCompare SUBSCHEMA_DATA_COMPARATOR =
        new SubSchemaDataDeepComparator();

    public static final DeepCompare FIELDDATA_COMPARATOR = new FieldDataDeepComparator();
    private SubSchemaData subSchemaDataA;
    private SubSchemaData subSchemaDataB;
    private SubSchemaData subSchemaDataC;

    private ExtendedSubSchemaData subSchemaDataD;

    private Collection<Entity> entitiesForTesting;

    public  SubSchemaDataTestFixture(SubSchemaTestFixture subSchemaTestFixture) {
        subSchemaDataA = new SubSchemaData(subSchemaTestFixture.getSubSchemaA());
        subSchemaDataB = new SubSchemaData(subSchemaTestFixture.getSubSchemaB());
        subSchemaDataC = new SubSchemaData(subSchemaTestFixture.getSubSchemaC());
        subSchemaDataD = new ExtendedSubSchemaData(subSchemaDataA);
        
    }
    
    public Collection<Entity> getEntitiesForDeepComparatorTesting() {
        if (entitiesForTesting == null) {
            entitiesForTesting = new ArrayList<Entity>();
            entitiesForTesting.add(subSchemaDataA);
            entitiesForTesting.add(subSchemaDataC);
        }
        return entitiesForTesting;
    }


    public SubSchemaData getSubSchemaDataA() {
        return subSchemaDataA;
    }


    public SubSchemaData getSubSchemaDataB() {
        return subSchemaDataB;
    }


    public SubSchemaData getSubSchemaDataC() {
        return subSchemaDataC;
    }


    public ExtendedSubSchemaData getSubSchemaDataD() {
        return subSchemaDataD;
    }


    public Collection<Entity> getEntitiesForTesting() {
        return entitiesForTesting;
    }


    /**
     *
     * SubReportDataDeepComparator.
     *
     */
    public static class SubSchemaDataDeepComparator extends AbstractDeepComparator {

        public boolean allowCompare(Entity retrieved, Entity loaded) {
            return (retrieved instanceof SubSchemaData) && (loaded instanceof SubSchemaData);
        }

        public void deepCompare(Entity retrievedEntity, Entity loadedEntity) {
            Assert.assertTrue("Can only compare " + SubSchemaData.class.getName() + ". arg1 "
                    + retrievedEntity.getClass().getName() + " arg2: " + loadedEntity.getClass().getName(),
                    allowCompare(retrievedEntity, loadedEntity));

            SubSchemaData retrieved = (SubSchemaData) retrievedEntity;
            SubSchemaData loaded = (SubSchemaData) loadedEntity;

            Assert.assertEquals(retrieved.getClass(), loaded.getClass());


//            SchemaTestFixture.SCHEMA_COMPARATOR.deepCompare(
//                    retrieved.getSchema(), loaded.getSchema());

//            SubReportDataTestFixture.FIELDDATA_COMPARATOR.deepCompare(
//            retrieved.getPostData(), loaded.getPostData(), true);

        }

    }

    /**
     *
     * PostDataDeepComparator.
     *
     */
    public static class FieldDataDeepComparator extends AbstractDeepComparator {

        public boolean allowCompare(Entity retrieved, Entity loaded) {
            return (retrieved instanceof FieldData) && (loaded instanceof FieldData);
        }


        public void deepCompare(Entity retrievedEntity, Entity loadedEntity) {
            Assert.assertTrue("Can only compare " + FieldData.class.getName() + ". arg1 "
                    + retrievedEntity.getClass().getName() + " arg2: " + loadedEntity.getClass().getName(),
                    allowCompare(retrievedEntity, loadedEntity));

            FieldData retrieved = (FieldData) retrievedEntity;
            FieldData loaded = (FieldData) loadedEntity;

            Assert.assertEquals(retrieved.getCode(), loaded.getCode());
            Assert.assertEquals(retrieved.getComment(), loaded.getComment());

//            AccountTestFixture.FIELD_COMPARATOR.deepCompare(retrieved.getField(), loaded.getField());
            // When loading from Hibernate we expect class to be FieldData but retrived are some other
            // non abstract class
            Class<FieldData> loadedClass = HibernateProxyHelper.getClassWithoutInitializingProxy(loaded);
            Assert.assertEquals(FieldData.class, loadedClass);
            Assert.assertFalse(retrieved.getClass().equals(FieldData.class));
            Assert.assertFalse(loaded.getClass().equals(FieldData.class));

//            Assert.assertEquals(retrieved.getClass(), loaded.getClass());
//            Assert.assertEquals(retrieved.getPeriod(), loaded.getPeriod());
//            Assert.assertEquals(retrieved.getPostDataType(), loaded.getPostDataType());

/*
            if (retrieved instanceof BoolPostData) {
                BoolPostDataDataTestFixture.BOOLEAN_FIELD_DATA_COMPARATOR.deepCompare(retrieved, loaded);
            }
*/

        }

    }

    /**
     * ExtendedSubReportData.
     *
     */
    @SuppressWarnings("serial")
    public class ExtendedSubSchemaData extends SubSchemaData {
        public ExtendedSubSchemaData(SubSchemaData subSchemaData) {
            super(subSchemaData.getSubSchema());
        }
    }

}