/*******************************************************************************
 * Copyright (c) 2005, 2009 SAP. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     SAP - initial API and implementation
 ******************************************************************************/

package org.eclipse.persistence.testing.tests.wdf.jpa1.simple;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.sql.DataSource;

import org.eclipse.persistence.platform.database.SQLServerPlatform;
import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.framework.wdf.Skip;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Department;
import org.eclipse.persistence.testing.models.wdf.jpa1.types.BasicTypesPropertyAccess;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

public class BufferReadTest extends JPA1Base {

    private static final long SECONDS = 0;
    private static final Integer KEY = Integer.valueOf(1);
    private static final Integer MISS = Integer.valueOf(2);
    private static final boolean PRINTLN = false;
    private EntityManager em;

    @Override
    protected void setup() {
        JPAEnvironment env = getEnvironment();
        em = env.getEntityManager();
        try {
            BasicTypesPropertyAccess data = new BasicTypesPropertyAccess(1);
            data.fill();
            data.setSerializable(null);
            data.setWrapperByteArray2Binary(null);
            data.setWrapperByteArray2Blob(null);
            data.setWrapperByteArray2Longvarbinary(null);
            data.setWrapperCharacterArray2Clob(null);
            data.setWrapperCharacterArray2Varchar(null);
            env.beginTransaction(em);
            Department department = new Department(1, "something");
            em.persist(data);
            em.persist(department);
            env.commitTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testFindOutsideTransaction() {
        Action action = new Action() {
            public void run() {
                em.clear();
                em.find(BasicTypesPropertyAccess.class, KEY);
            }

            public String description() {
                return "find outside transaction (large, hit)";
            }

            public void prepare() {
            }

            public void tearDown() {
            }
        };
        doTest(action);
    }

    @Test
    public void testFindOutsideTransactionSmall() {
        Action action = new Action() {
            public void run() {
                em.clear();
                em.find(Department.class, KEY);
            }

            public String description() {
                return "find outside transaction (small, hit)";
            }

            public void prepare() {
            }

            public void tearDown() {
            }
        };
        doTest(action);
    }

    @Test
    public void testQueryCompleteOutsideTransactionSmall() {
        Action action = new Action() {
            Query query;

            public void run() {
                em.clear();
            }

            public String description() {
                return "query complete outside transaction (small, hit)";
            }

            public void prepare() {
                query = em.createQuery("select d from Department d where d.id = ?1");
                query.setParameter(1, Integer.valueOf(1));
                query.getSingleResult();
            }

            public void tearDown() {
            }
        };
        doTest(action);
    }

    @Test
    public void testQueryExecuteOnlyOutsideTransactionSmall() {
        final JPAEnvironment environment = getEnvironment();
        final EntityManager myEm = environment.getEntityManager();
        Action action = new Action() {
            Query query;

            public void run() {
                myEm.clear();
                query.getSingleResult();
            }

            public String description() {
                return "query execute outside transaction (small, hit)";
            }

            public void prepare() {
                getEnvironment().beginTransaction(myEm);
                query = myEm.createQuery("select d from Department d where d.id = ?1");
                query.setParameter(1, Integer.valueOf(1));
            }

            public void tearDown() {
            }

        };
        doTest(action);
    }

    @Test
    public void testQueryExecuteOnlyOutsideTransactionNew() {
        final JPAEnvironment environment = getEnvironment();
        final EntityManager myEm = environment.getEntityManager();
        Action action = new Action() {
            Query query;

            public void run() {
                myEm.clear();
                query.getSingleResult();
            }

            public String description() {
                return "query execute outside transaction (new, hit)";
            }

            public void prepare() {
                getEnvironment().beginTransaction(myEm);
                query = myEm
                        .createQuery("select new org.eclipse.persistence.testing.models.wdf.jpa1.employee.Department(d.id, d.name) from Department d where d.id = ?1");
                query.setParameter(1, Integer.valueOf(1));
            }

            public void tearDown() {
                if (getEnvironment().isTransactionActive(myEm)) {
                    myEm.getTransaction().rollback();
                }
                closeEntityManager(myEm);
            }
        };
        doTest(action);
    }

    @Test
    public void testNamedQueryCompleteOutsideTransactionSmall() {
        Action action = new Action() {
            public void run() {
                em.clear();
                Query query = em.createNamedQuery("getDepartmentById");
                query.setParameter(1, Integer.valueOf(1));
                query.getSingleResult();
            }

            public String description() {
                return "query named complete outside transaction (small, hit)";
            }

            public void tearDown() {
            }

            public void prepare() {
            }
        };
        doTest(action);
    }

    @Test
    public void testNamedQueryExecuteOnlyOutsideTransactionSmall() {
        final JPAEnvironment environment = getEnvironment();
        final EntityManager myEm = environment.getEntityManager();
        Action action = new Action() {
            Query query;

            public void run() {
                myEm.clear();
                query.getSingleResult();
            }

            public String description() {
                return "query named execute outside transaction (small, hit)";
            }

            public void prepare() {
                getEnvironment().beginTransaction(myEm);
                query = myEm.createNamedQuery("getDepartmentById");
                query.setParameter(1, Integer.valueOf(1));
            }

            public void tearDown() {
            }
        };
        doTest(action);
    }

    @Test
    public void testNativeEntityExecuteOnlyOutsideTransactionSmall() {
        final JPAEnvironment environment = getEnvironment();
        final EntityManager myEm = environment.getEntityManager();
        Action action = new Action() {
            Query query;

            public void run() {
                myEm.clear();
                query.getSingleResult();
            }

            public String description() {
                return "native entity execute outside transaction (small, hit)";
            }

            public void prepare() {
                query = myEm.createNativeQuery("select ID, NAME, VERSION from TMP_DEP where ID = 1", Department.class);
            }

            public void tearDown() {

            }
        };
        doTest(action);
    }

    @Test
    @Skip(databases=SQLServerPlatform.class)
    public void testNativeFieldsExecuteOnlyOutsideTransactionSmall() {
        final JPAEnvironment environment = getEnvironment();
        final EntityManager myEm = environment.getEntityManager();
        Action action = new Action() {
            Query query;

            public void run() {
                myEm.clear();
                Object object = query.getSingleResult();
                Object[] array = (Object[]) object;
                int id = ((Number) array[0]).intValue();
                String name = (String) array[1];
                new Department(id, name);
            }

            public String description() {
                return "native fields execute outside transaction (small, hit)";
            }

            public void prepare() {
                query = myEm.createNamedQuery("getDepartmentFieldByField1");
            }

            public void tearDown() {
            }
        };
        doTest(action);
    }

    @Test
    public void testJDBCBestSmall() throws SQLException {
        final DataSource dataSource = getEnvironment().getDataSource();
        final Connection connection = dataSource.getConnection();
        connection.setAutoCommit(false);
        try {
            final PreparedStatement preparedStatement = connection
                    .prepareStatement("select ID, NAME from TMP_DEP where ID = ?");
            try {
                preparedStatement.setInt(1, 1);
                Action action = new Action() {
                    public void run() {
                        try {
                            ResultSet rs = preparedStatement.executeQuery();
                            try {
                                rs.next();
                                new Department(rs.getInt(1), rs.getString(2));
                            } finally {
                                rs.close();
                            }
                        } catch (SQLException e) {
                            throw new RuntimeException(e);
                        }
                    }

                    public void tearDown() {
                    }

                    public String description() {
                        return "JDBC excluding prepare and set (small, hit)";
                    }

                    public void prepare() {
                    }
                };
                doTest(action);
            } finally {
                preparedStatement.close();
            }
        } finally {

            connection.close();
        }
    }

    @Test
    public void testJDBCInclusivePreapreSmall() throws SQLException {
        final DataSource dataSource = getEnvironment().getDataSource();
        final Connection connection = dataSource.getConnection();
        connection.setAutoCommit(false);
        try {
            Action action = new Action() {
                public void run() {
                    try {
                        final PreparedStatement preparedStatement = connection
                                .prepareStatement("select ID, NAME from TMP_DEP where ID = ?");
                        preparedStatement.setInt(1, 1);
                        try {
                            ResultSet rs = preparedStatement.executeQuery();
                            try {
                                rs.next();
                                new Department(rs.getInt(1), rs.getString(2));
                            } finally {
                                rs.close();
                                connection.commit();
                            }
                        } finally {
                            preparedStatement.close();
                        }
                    } catch (SQLException e) {
                        throw new RuntimeException(e);
                    }
                }

                public void tearDown() {
                }

                public String description() {
                    return "JDBC incuding prepare (small, hit)";
                }

                public void prepare() {
                }
            };
            doTest(action);
        } finally {

            connection.close();
        }
    }

    private void printRate(String description, int i) {
        // $JL-SYS_OUT_ERR$
        System.out.println(description + ": " + i + " in " + SECONDS + " second[s] (" + ((SECONDS * 1000.0) / i)
                + " milliseconds)");
    }

    @Test
    public void testNotFound() {
        Action action = new Action() {
            public void run() {
                em.clear();
                em.find(BasicTypesPropertyAccess.class, MISS);
            }

            public String description() {
                return "find outside transaction (miss)";
            }

            public void tearDown() {
            }

            public void prepare() {
            }
        };
        doTest(action);
    }

    @Test
    public void testFlush() {
        Action action = new Action() {
            public void run() {
                em.flush();
            }

            public void tearDown() {
            }

            public String description() {
                return "flush (unchanged)";
            }

            public void prepare() {
            }
        };
        doTest(action);
    }

    private void doTest(Action action) {
        JPAEnvironment env = getEnvironment();
        em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            em.find(BasicTypesPropertyAccess.class, KEY);
            em.find(Department.class, KEY);
            action.prepare();
            long start = System.currentTimeMillis();
            long end = start + 10;
            while (System.currentTimeMillis() < end) {
                action.run(); // 10 ms warmup in order to fill JIT
            }
            start = System.currentTimeMillis();
            end = start + 1000 * SECONDS;
            int i = 0;
            while (System.currentTimeMillis() < end) {
                // for (int j = 0; j < 10; j++) {
                action.run();
                i++;
            }
            if (PRINTLN) {
                printRate(action.description(), i);
            }

        } finally {
            action.tearDown();
            closeEntityManager(em);
        }
    }

    private interface Action {
        void prepare();

        void run();

        void tearDown();

        String description();
    }
}
