/*
 * Copyright (C) 2010 Google, Inc.
 *
 * Licensed 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 com.google.inject.persist.jpa;

import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.persist.PersistService;
import com.google.inject.persist.Transactional;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import junit.framework.TestCase;

/**
 * This test asserts class level @Transactional annotation behavior.
 *
 * <p>Class-level @Transactional is a shortcut if all non-private methods in the class are meant to
 * be transactional.
 *
 * @author Dhanji R. Prasanna (dhanji@gmail.com)
 */

public class ClassLevelManagedLocalTransactionsTest extends TestCase {
  private Injector injector;
  private static final String UNIQUE_TEXT = "JPAsome unique text88888" + new Date();
  private static final String UNIQUE_TEXT_2 = "JPAsome asda unique teasdalsdplasdxt" + new Date();
  private static final String TRANSIENT_UNIQUE_TEXT =
      "JPAsome other unique texaksoksojadasdt" + new Date();

  @Override
  public void setUp() {
    injector = Guice.createInjector(new JpaPersistModule("testUnit"));

    //startup persistence
    injector.getInstance(PersistService.class).start();
  }

  @Override
  public void tearDown() {
    injector.getInstance(PersistService.class).stop();
    injector = null;
  }

  public void testSimpleTransaction() {
    injector.getInstance(TransactionalObject.class).runOperationInTxn();

    EntityManager session = injector.getInstance(EntityManager.class);
    assertFalse(
        "EntityManager was not closed by transactional service",
        session.getTransaction().isActive());

    //test that the data has been stored
    session.getTransaction().begin();
    Object result =
        session
            .createQuery("from JpaTestEntity where text = :text")
            .setParameter("text", UNIQUE_TEXT)
            .getSingleResult();

    session.getTransaction().commit();

    assertTrue("odd result returned fatal", result instanceof JpaTestEntity);

    assertEquals(
        "queried entity did not match--did automatic txn fail?",
        UNIQUE_TEXT,
        (((JpaTestEntity) result).getText()));
  }

  public void testSimpleTransactionRollbackOnChecked() {
    try {
      injector.getInstance(TransactionalObject2.class).runOperationInTxnThrowingChecked();
    } catch (IOException e) {
      //ignore
    }

    EntityManager session = injector.getInstance(EntityManager.class);
    assertFalse(
        "EntityManager was not closed by transactional service (rollback didnt happen?)",
        session.getTransaction().isActive());

    //test that the data has been stored
    session.getTransaction().begin();
    List<?> result =
        session
            .createQuery("from JpaTestEntity where text = :text")
            .setParameter("text", TRANSIENT_UNIQUE_TEXT)
            .getResultList();

    session.getTransaction().commit();

    assertTrue("a result was returned! rollback sure didnt happen!!!", result.isEmpty());
  }

  public void testSimpleTransactionRollbackOnCheckedExcepting() {
    Exception ex = null;
    try {
      injector.getInstance(TransactionalObject3.class).runOperationInTxnThrowingCheckedExcepting();
      fail("Exception was not thrown by test txn-al method!");
    } catch (IOException e) {
      //ignored
    }

    EntityManager session = injector.getInstance(EntityManager.class);
    assertFalse(
        "Txn was not closed by transactional service (commit didnt happen?)",
        session.getTransaction().isActive());

    //test that the data has been stored
    session.getTransaction().begin();
    Object result =
        session
            .createQuery("from JpaTestEntity where text = :text")
            .setParameter("text", UNIQUE_TEXT_2)
            .getSingleResult();

    session.getTransaction().commit();

    assertNotNull("a result was not returned! rollback happened anyway (ignore failed)!!!", result);
  }

  public void testSimpleTransactionRollbackOnUnchecked() {
    try {
      injector.getInstance(TransactionalObject4.class).runOperationInTxnThrowingUnchecked();
    } catch (RuntimeException re) {
      //ignore
    }

    EntityManager session = injector.getInstance(EntityManager.class);
    assertFalse(
        "EntityManager was not closed by transactional service (rollback didnt happen?)",
        session.getTransaction().isActive());

    //test that the data has been stored
    session.getTransaction().begin();
    List<?> result =
        session
            .createQuery("from JpaTestEntity where text = :text")
            .setParameter("text", TRANSIENT_UNIQUE_TEXT)
            .getResultList();

    session.getTransaction().commit();

    assertTrue("a result was returned! rollback sure didnt happen!!!", result.isEmpty());
  }

  @Transactional
  public static class TransactionalObject {
    @Inject EntityManager session;

    public void runOperationInTxn() {
      assertTrue(session.getTransaction().isActive());
      JpaTestEntity entity = new JpaTestEntity();
      entity.setText(UNIQUE_TEXT);
      session.persist(entity);
    }
  }

  @Transactional
  public static class TransactionalObject4 {
    @Inject EntityManager session;

    @Transactional
    public void runOperationInTxnThrowingUnchecked() {
      assertTrue(session.getTransaction().isActive());
      JpaTestEntity entity = new JpaTestEntity();
      entity.setText(TRANSIENT_UNIQUE_TEXT);
      session.persist(entity);

      throw new IllegalStateException();
    }
  }

  @Transactional(rollbackOn = IOException.class, ignore = FileNotFoundException.class)
  public static class TransactionalObject3 {
    @Inject EntityManager session;

    public void runOperationInTxnThrowingCheckedExcepting() throws IOException {
      assertTrue(session.getTransaction().isActive());
      JpaTestEntity entity = new JpaTestEntity();
      entity.setText(UNIQUE_TEXT_2);
      session.persist(entity);

      throw new FileNotFoundException();
    }
  }

  @Transactional(rollbackOn = IOException.class)
  public static class TransactionalObject2 {
    @Inject EntityManager session;

    public void runOperationInTxnThrowingChecked() throws IOException {
      assertTrue(session.getTransaction().isActive());
      JpaTestEntity entity = new JpaTestEntity();
      entity.setText(TRANSIENT_UNIQUE_TEXT);
      session.persist(entity);

      throw new IOException();
    }
  }
}
