/*
 * 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.jdo.tck.api.instancecallbacks;

import javax.jdo.JDODataStoreException;
import javax.jdo.JDOUserException;
import javax.jdo.Transaction;

import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.instancecallbacks.InstanceCallbackClass;
import org.apache.jdo.tck.pc.instancecallbacks.InstanceCallbackNonPersistFdsClass;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 *<B>Title:</B> Calling InstanceCallbacks Prestore Method
 *<BR>
 *<B>Keywords:</B> instancecallbacks
 *<BR>
 *<B>Assertion ID:</B> A10.2-1.
 *<BR>
 *<B>Assertion Description: </B>
The <code>jdoPreStore()</code> method of a class implementing
<code>InstanceCallbacks</code> is called before the values are
stored from the instance to the <code>StateManager</code>.

 */

/*
 *  Use non-managed and transactional values to construct a persistent attribute value to store in database.
 *   Check to see this constructed persistent attribute got stored.
 *
 *  jdoPreStore() should have been called when obj1 and obj2 were created.
 *  jdoPreStore() should have been called again when obj2 was modified.
 *  jdoPreStore() should not be called a second time on obj1 because it was not modified.

 /* 
 This test is accomplished in three transactions. 
     1)  object1 and object2 are created.  At commit, we expect jdoPreStore()
         to be called on each and calculate values of persistent attributes from non-presistent attributes. 
     2)  Retrieve object1 and object2 from the database and verify the persistent attributes
         have values calculated in the jdoPreStore()s called in the previous transaction.
         Change non-persistent fields in each but only change a persistent field in one of them. 
     3)  Retrieve object1 and object2 from the database and verify that again jdoPreStore()
         was called for each in the previous transaction. 
*/ 

public class CallingJdoPrestore extends JDO_Test {

    /** */
    private static final String ASSERTION_FAILED = 
        "Assertion A10.2-1 (CallingJdoPrestore) failed";

    /**
     * The <code>main</code> is called when the class
     * is directly executed from the command line.
     * @param args The arguments passed to the program.
     */
    public static void main(String[] args) {
        BatchTestRunner.run(CallingJdoPrestore.class);
    }
    
    /**
     * @see org.apache.jdo.tck.JDO_Test#localSetUp()
     */
    @Override
    protected void localSetUp() {
        addTearDownClass(InstanceCallbackNonPersistFdsClass.class);
    }
    
    /** */
    public void test() {
        pm = getPM();
        Transaction t = pm.currentTransaction(); 

        InstanceCallbackClass.initializeStaticsForTest();

        InstanceCallbackClass.performPreStoreTests = true;
        t.begin();        
        int expectedIntValue1, expectedIntValue2;
        float expectedFloatValue1, expectedFloatValue2;
        
        int origIntValue1 = 10, origIntValue2 = 12;
        float origFloatValue1 = 2.5f, origFloatValue2 = -3.0f;
        
        // create two instances
        
        InstanceCallbackNonPersistFdsClass obj1 = new InstanceCallbackNonPersistFdsClass(origFloatValue1, origIntValue1);
        pm.makePersistent(obj1);
        Object objPtr1 = pm.getObjectId (obj1);
        obj1.setNonPersist(5, (char)10, .25, (short)100);
        expectedIntValue1 = obj1.calcIntValue();
        expectedFloatValue1 = obj1.calcFloatValue();
        
        InstanceCallbackNonPersistFdsClass obj2 = new InstanceCallbackNonPersistFdsClass(origFloatValue2, origIntValue2);
        pm.makePersistent(obj2);
        Object objPtr2 = pm.getObjectId (obj2);
        obj2.setNonPersist(2, (char)125, .1, (short)750);
        expectedIntValue2 = obj2.calcIntValue();
        expectedFloatValue2 = obj2.calcFloatValue();

        t.commit();
        
        t.begin();
        // read both objects back in to determine persistent state is as expected.
        try {
            obj1 = (InstanceCallbackNonPersistFdsClass)pm.getObjectById(objPtr1, true);
            checkValues("Object1 created and read back in:  ", origIntValue1, expectedIntValue1, obj1.intValue);
            checkValues("Object1 created and read back in:  ", origFloatValue1, expectedFloatValue1, obj1.floatValue);
            origIntValue1 = obj1.intValue;
            origFloatValue1 = obj1.floatValue;
            obj1.setNonManaged(-1, (char)62);
            expectedIntValue1 = obj1.calcIntValue();
            expectedFloatValue1 = obj1.calcFloatValue();
        } catch (JDOUserException e) {
            // could not locate persistent object created in previous transaction
            fail(ASSERTION_FAILED, "CallingJdoPrestore: Failed to find object obj1 created in previous transaction, got " + e);
            return;
        } catch (JDODataStoreException e) {
            // could not locate persistent object created in previous transaction
            fail(ASSERTION_FAILED, "CallingJdoPrestore: Failed to find object obj1 created in previous transaction, got " + e);
            return;
        }

        try {
            obj2 = (InstanceCallbackNonPersistFdsClass)pm.getObjectById(objPtr2, true);
            checkValues("Object2 created and read back in:  ", origIntValue2, expectedIntValue2, obj2.intValue);
            checkValues("Object2 created and read back in:  ", origFloatValue2, expectedFloatValue2, obj2.floatValue);
            origIntValue2 = obj2.intValue;
            origFloatValue2 = obj2.floatValue;
            obj2.setNonPersist(12, (char)30, 5.0, (short)137);
            expectedIntValue2 = obj2.calcIntValue();
            expectedFloatValue2 = obj2.calcFloatValue();
            
            // change obj2 making it persistent dirty (leave obj1 persistent clean).
            obj2.incrementIntValue();
        } catch (JDOUserException e) {
            // could not locate persistent object created in previous transaction
            fail(ASSERTION_FAILED, "CallingJdoPrestore: Failed to find object obj2 created in previous transaction, got " + e);
            return;
        } catch (JDODataStoreException e) {
            // could not locate persistent object created in previous transaction
            fail(ASSERTION_FAILED, "CallingJdoPrestore: Failed to find object obj2 created in previous transaction, got " + e);
            return;
        }

        t.commit();
        
        t.begin();
        // read both objects back in to determine persistent state is as expected.
         try {
            // obj1 not made dirty, so jdoPreStore() should not have been called.
            obj1 = (InstanceCallbackNonPersistFdsClass)pm.getObjectById(objPtr1, true);
            checkValues("Object1, did not expect jdoPreStore to be called:  ", origIntValue1, origIntValue1, obj1.intValue);
            checkValues("Object1, did not expect jdoPreStore to be called:  ", origFloatValue1, origFloatValue1, obj1.floatValue);
        } catch (JDOUserException e) {
            // could not locate persistent object created in previous transaction
            fail(ASSERTION_FAILED, "CallingJdoPrestore: Failed to find object obj1 created in previous transaction, got " + e);
            return;
        } catch (JDODataStoreException e) {
            // could not locate persistent object created in previous transaction
            fail(ASSERTION_FAILED, "CallingJdoPrestore: Failed to find object obj1 created in previous transaction, got " + e);
            return;
        }
        
        try {
            obj2 = (InstanceCallbackNonPersistFdsClass)pm.getObjectById(objPtr2, true);
            checkValues("Object2, expected jdoPreStore() to be called:  ", origIntValue2, expectedIntValue2, obj2.intValue);
            checkValues("Object2, expected jdoPreStore() to be called:  ", origFloatValue2, expectedFloatValue2, obj2.floatValue);
        } catch (JDOUserException e) {
            // could not locate persistent object created in previous transaction
            fail(ASSERTION_FAILED, "CallingJdoPrestore: Failed to find object obj2 created in previous transaction, got " + e);
            return;
        } catch (JDODataStoreException e) {
            // could not locate persistent object created in previous transaction
            fail(ASSERTION_FAILED, "CallingJdoPrestore: Failed to find object obj2 created in previous transaction, got " + e);
            return;
        }
        t.rollback();
        pm.close();
        pm = null;
    }
    
    /** */
    void checkValues(String title, int origIntValue, int expectedIntValue, int intValue) {
        if(expectedIntValue != intValue) {
            fail(ASSERTION_FAILED, 
                 title + "Original persistent intValue is " + origIntValue + 
                 ", expected " + expectedIntValue + 
                 ".  Instead intValue is " + intValue);
        }
    }
    
    /** */
    void checkValues(String title, float origFloatValue, float expectedFloatValue, float floatValue) {
        if(expectedFloatValue != floatValue) {
            fail(ASSERTION_FAILED,
                 title + "Original persistent floatValue is " + origFloatValue + 
                 ", expected " + expectedFloatValue +
                 ".  Instead floatVal is " + floatValue);
        }
    }
}
