/*
 * 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.annotations;

import javax.persistence.EntityManager;

import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.strats.NoneVersionStrategy;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;

/**
 * Test for opt-lock
 *
 * @author Steve Kim
 */
public class TestVersion extends SingleEMFTestCase {

    public void setUp() {
        setUp(AnnoTest1.class, AnnoTest2.class, AnnoTest3.class, Flat1.class,
            EmbedOwner.class, EmbedValue.class, CLEAR_TABLES);

        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        AnnoTest1 test1 = new AnnoTest1();
        test1.setPk(new Long(5));
        test1.setBasic(50);
        test1.setTransient(500);
        em.persist(test1);

        AnnoTest2 test2 = new AnnoTest2();
        test2.setPk1(5);
        test2.setPk2("bar");
        test2.setBasic("50");
        em.persist(test2);

        AnnoTest3 test3 = new AnnoTest3();
        test3.setPk(new Long(3));
        test3.setBasic2(50);
        em.persist(test3);
        em.getTransaction().commit();
        em.close();
    }

    public void testVersionNumeric() {
        EntityManager em1 = emf.createEntityManager();
        em1.getTransaction().begin();
        EntityManager em2 = emf.createEntityManager();
        em2.getTransaction().begin();

        AnnoTest1 pc1 = em1.find(AnnoTest1.class, new Long(5));
        AnnoTest1 pc2 = em2.find(AnnoTest1.class, new Long(5));
        assertEquals(1, pc1.getVersion());
        assertEquals(1, pc2.getVersion());
        assertEquals(0, pc1.getTransient());
        pc1.setBasic(75);
        pc2.setBasic(75);
        em1.getTransaction().commit();
        em1.close();

        em1 = emf.createEntityManager();
        pc1 = em1.find(AnnoTest1.class, new Long(5));
        assertEquals(2, pc1.getVersion());
        em1.close();
        try {
            em2.getTransaction().commit();
            fail("Optimistic fail");
        } catch (Exception e) {
        } finally {
            em2.close();
        }
    }

    public void testVersionTimestamp() {
        // ensure that some time has passed
        // since the records were created
        try {
            Thread.sleep(50);
        }
        catch (InterruptedException e) {
            // do nothing
        }
        
        EntityManager em1 = emf.createEntityManager();
        em1.getTransaction().begin();
        EntityManager em2 = emf.createEntityManager();
        em2.getTransaction().begin();

        AnnoTest2 pc1 = em1.find(AnnoTest2.class,
            new AnnoTest2.Oid(5, "bar"));
        AnnoTest2 pc2 = em2.find(AnnoTest2.class,
            new AnnoTest2.Oid(5, "bar"));
        assertNotNull(pc1.getVersion());
        assertEquals(pc1.getVersion(), pc2.getVersion());
        pc1.setBasic("75");
        pc2.setBasic("75");
        em1.getTransaction().commit();
        em1.close();

        em1 = emf.createEntityManager();
        pc1 = em1.find(AnnoTest2.class,
            new AnnoTest2.Oid(5, "bar"));
        java.util.Date pc1Version = pc1.getVersion();
        java.util.Date pc2Version = pc2.getVersion();
        assertTrue(pc1Version.compareTo(pc2Version) > 0);
        em1.close();
        try {
            em2.getTransaction().commit();
            fail("Optimistic fail");
        } catch (Exception e) {
        } finally {
            em2.close();
        }
    }

    public void testVersionSubclass() {
        EntityManager em1 = emf.createEntityManager();
        em1.getTransaction().begin();
        EntityManager em2 = emf.createEntityManager();
        em2.getTransaction().begin();

        AnnoTest3 pc1 = em1.find(AnnoTest3.class, new Long(3));
        AnnoTest3 pc2 = em2.find(AnnoTest3.class, new Long(3));
        assertEquals(1, pc1.getVersion());
        assertEquals(1, pc2.getVersion());
        pc1.setBasic2(75);
        pc2.setBasic2(75);
        em1.getTransaction().commit();
        em1.close();

        em1 = emf.createEntityManager();
        pc1 = em1.find(AnnoTest3.class, new Long(3));
        assertEquals(2, pc1.getVersion());
        em1.close();
        try {
            em2.getTransaction().commit();
            fail("Optimistic fail");
        } catch (Exception e) {
        } finally {
            em2.close();
        }
    }

    public void testVersionNoChange() {
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();

        AnnoTest1 pc = em.find(AnnoTest1.class, new Long(5));
        assertEquals(1, pc.getVersion());
        assertEquals(0, pc.getTransient());
        pc.setTransient(750);
        em.getTransaction().commit();
        em.close();

        em = emf.createEntityManager();
        pc = em.find(AnnoTest1.class, new Long(5));
        assertEquals(1, pc.getVersion());
        assertEquals(0, pc.getTransient());
        em.close();
    }

    public void testNoDefaultVersionWithoutFieldOrColumn() {
        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
            getMappingRepositoryInstance().getMapping(EmbedOwner.class, 
            null, true);
        assertEquals(NoneVersionStrategy.getInstance(),
            cls.getVersion().getStrategy());
        assertEquals(0, cls.getVersion().getColumns().length);
    }

    public void testVersionWithField() {
        ClassMapping cls = ((JDBCConfiguration) emf.getConfiguration()).
            getMappingRepositoryInstance().getMapping(AnnoTest1.class, 
            null, true);
        assertTrue(NoneVersionStrategy.getInstance() !=
            cls.getVersion().getStrategy());
        assertEquals(1, cls.getVersion().getColumns().length);
    }
}
