/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.transactions;

import javax.jdo.Constants;
import javax.jdo.JDOUnsupportedOptionException;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B>Set isolation level of transaction <br>
 * <B>Keywords:</B> persistencemanagerfactory <br>
 * <B>Assertion IDs:</B> A11.1-xxxx, A11.1-xxxx. <br>
 * <B>Assertion Description: </B> Transaction.getIsolationLevel() returns the value of the isolation
 * level. Transaction.setIsolationLevel(String) sets the value of the isolation level.
 */
public class SetIsolationLevel extends JDO_Test implements Constants {

  /** */
  private static final String ASSERTION_29_FAILED =
      "Assertion A13.4.2-29 (setIsolationLevel) failed: ";
  /** */
  private static final String ASSERTION_25_FAILED =
      "Assertion A13.4.2-25 (setIsolationLevel) failed: ";

  /** All specified isolation levels */
  private static final String[] isolationLevels =
      new String[] {
        TX_READ_UNCOMMITTED, TX_READ_COMMITTED, TX_REPEATABLE_READ, TX_SNAPSHOT, TX_SERIALIZABLE
      };

  /**
   * 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(SetIsolationLevel.class);
  }

  /** */
  @Override
  protected void localSetUp() {
    pm = getPM();
  }

  /** Set IsolationLevel to all values. */
  public void testSetIsolationLevelOutsideTransaction() {
    // iterate through all possible IsolationLevels
    for (String isolationLevel : isolationLevels) {
      setIsolationLevel(isolationLevel);
    }
    closePMF(pmf);
    failOnError();
  }

  /** Set IsolationLevel to all values within datastore transaction. */
  public void testSetIsolationLevelWithActiveDataStoreTransaction() {
    pm.currentTransaction().setOptimistic(false);
    pm.currentTransaction().begin();
    // iterate through all possible IsolationLevels
    for (String isolationLevel : isolationLevels) {
      try {
        pm.currentTransaction().setIsolationLevel(isolationLevel);
        appendMessage(
            ASSERTION_25_FAILED
                + "active datastore transaction; no exception thrown for "
                + "setIsolationLevel("
                + isolationLevel
                + ").");
      } catch (JDOUnsupportedOptionException ex) {
        // good catch
      } catch (Throwable t) {
        appendMessage(
            ASSERTION_25_FAILED
                + "active datastore transaction; "
                + "JDOUnsupportedOptionException not thrown for "
                + "setIsolationLevel("
                + isolationLevel
                + "). Unexpected exception: \n"
                + t);
      }
    }
    pm.currentTransaction().commit();
    closePMF(pmf);
    failOnError();
  }

  /** Set IsolationLevel to all values within optimistic transaction. */
  public void testSetIsolationLevelWithActiveOptimisticTransaction() {
    if (!isOptimisticSupported()) {
      printUnsupportedOptionalFeatureNotTested(
          "testSetIsolationLevelWithActiveOptimisticTransaction", "Optimistic");
      return;
    }
    pm.currentTransaction().setOptimistic(true);
    pm.currentTransaction().begin();
    // iterate through all possible IsolationLevels
    for (String isolationLevel : isolationLevels) {
      setIsolationLevel(isolationLevel);
    }
    pm.currentTransaction().commit();
    closePMF(pmf);
    failOnError();
  }

  /** */
  private void setIsolationLevel(String level) {
    Transaction tx = pm.currentTransaction();
    String property = PROPERTY_TRANSACTION_ISOLATION_LEVEL + "." + level;
    if (isSupported(property)) {
      tx.setIsolationLevel(level);
      String actual = tx.getIsolationLevel();
      if (!validLevelSubstitution(level, actual)) {
        appendMessage(
            ASSERTION_29_FAILED
                + "\nIsolationLevel set to "
                + level
                + "; value returned by Transaction is "
                + actual);
      }
    } else {
      try {
        tx.setIsolationLevel(level);
        // no exception thrown; bad
        appendMessage(ASSERTION_29_FAILED + "\nThe expected JDOUserException was not thrown.");
      } catch (JDOUnsupportedOptionException ex) {
        // good catch
        return;
      } catch (Throwable t) {
        // wrong exception thrown; bad
        appendMessage(
            ASSERTION_29_FAILED
                + "active datastore transaction; "
                + "JDOUnsupportedOptionException not thrown for "
                + "setIsolationLevel("
                + level
                + "). Unexpected exception: \n"
                + t);
        return;
      }
    }
  }
}
