/*
 * 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.mapping;

import java.util.Date;
import org.apache.jdo.tck.pc.company.Employee;
import org.apache.jdo.tck.pc.company.FullTimeEmployee;
import org.apache.jdo.tck.pc.company.MedicalInsurance;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B>Relationship1To1NoRelationships <br>
 * <B>Keywords:</B> mapping, managed relationships <br>
 * <B>Assertion ID:</B> A15.3-14 <br>
 * <B>Assertion Description: Regardless of which side changes the relationship, flush (whether done
 * as part of commit or explicitly by the user) will modify the datastore to reflect the change and
 * will update the memory model for consistency...</B>
 */
public class Relationship1To1NoRelationships extends AbstractRelationshipTest {

  String testMethod = null;
  private static final String ASSERTION_FAILED =
      "Assertion A15-3.14 (Relationship1To1NoRelationships) failed: ";

  Object emp1Oid = null;
  Object emp2Oid = null;
  Object medIns1Oid = null;
  Object medIns2Oid = null;
  Employee emp1 = null;
  Employee emp2 = null;
  MedicalInsurance medIns1 = null;
  MedicalInsurance medIns2 = null;

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

  /**
   * @see AbstractRelationshipTest#localSetUp()
   */
  @Override
  protected void localSetUp() {
    super.localSetUp();
    if (isTestToBePerformed) {
      getPM();
      pm.currentTransaction().begin();

      emp1Oid = getOidByName("emp1");
      medIns1Oid = getOidByName("medicalIns1");
      emp1 = (Employee) pm.getObjectById(emp1Oid);
      medIns1 = (MedicalInsurance) pm.getObjectById(medIns1Oid);

      // Preconditions
      assertTrue(
          ASSERTION_FAILED
              + ": Test aborted, precondition is false; "
              + "expected emp.getMedicalInsurance()to be null",
          emp1.getMedicalInsurance() == null);
      assertTrue(
          ASSERTION_FAILED
              + ": Test aborted, precondition is false; "
              + "expected ins.getEmployee() to be null",
          medIns1.getEmployee() == null);
    }
  }

  /** */
  public void testSetToExistingFromMappedSide() {
    testMethod = "testSetToExistingFromMappedSide";
    if (isTestToBePerformed) {

      // Set relationship
      medIns1.setEmployee(emp1);
      pm.flush();

      // Postcondition
      deferredAssertTrue(
          emp1.getMedicalInsurance() == medIns1,
          ASSERTION_FAILED + testMethod,
          "Postcondition is false; " + "other side of relationship not set on flush");
      pm.currentTransaction().commit();
      cleanupPM();
      getPM();

      pm.currentTransaction().begin();
      emp1 = (Employee) pm.getObjectById(emp1Oid);
      medIns1 = (MedicalInsurance) pm.getObjectById(medIns1Oid);
      deferredAssertTrue(
          emp1.getMedicalInsurance() == medIns1,
          ASSERTION_FAILED + testMethod,
          "In new transaction, postcondition is false; "
              + "other side of relationship is not set.");
      pm.currentTransaction().commit();

      failOnError();
    }
  }

  /** */
  public void testSetToExistingFromMappedBySide() {
    testMethod = "testSetToExistingFromMappedBySide";
    if (isTestToBePerformed) {

      // Set relationship
      emp1.setMedicalInsurance(medIns1);
      pm.flush();

      // Postcondition
      deferredAssertTrue(
          medIns1.getEmployee() == emp1,
          ASSERTION_FAILED + testMethod,
          "Postcondition is false; " + "other side of relationship not set on flush");
      pm.currentTransaction().commit();
      cleanupPM();
      getPM();

      pm.currentTransaction().begin();
      emp1 = (Employee) pm.getObjectById(emp1Oid);
      medIns1 = (MedicalInsurance) pm.getObjectById(medIns1Oid);
      deferredAssertTrue(
          medIns1.getEmployee() == emp1,
          ASSERTION_FAILED + testMethod,
          "In new transaction, postcondition is false; "
              + "other side of relationship is not set.");
      pm.currentTransaction().commit();

      failOnError();
    }
  }

  /** */
  public void testSetToNewFromMappedSide() {
    testMethod = "testSetToNewFromMappedSide";
    if (isTestToBePerformed) {

      // Set relationship
      Employee empNew =
          new FullTimeEmployee(99, "Matthew", "", "Adams", new Date(0L), new Date(10000L), 125000);
      pm.makePersistent(empNew);
      medIns1.setEmployee(empNew);
      Object empNewOid = pm.getObjectId(empNew);
      pm.flush();

      // Postcondition
      deferredAssertTrue(
          empNew.getMedicalInsurance() == medIns1,
          ASSERTION_FAILED + testMethod,
          "Postcondition is false; " + "other side of relationship not set on flush");

      pm.currentTransaction().commit();
      cleanupPM();
      getPM();

      pm.currentTransaction().begin();
      emp1 = (Employee) pm.getObjectById(emp1Oid);
      empNew = (Employee) pm.getObjectById(empNewOid);
      medIns1 = (MedicalInsurance) pm.getObjectById(medIns1Oid);
      deferredAssertTrue(
          empNew.getMedicalInsurance() == medIns1,
          ASSERTION_FAILED + testMethod,
          "Postcondition is false; " + "other side of relationship not set in new pm");
      pm.currentTransaction().commit();

      failOnError();
    }
  }

  /** */
  public void testSetToNewFromMappedBySide() {
    testMethod = "testSetToNewFromMappedBySide";
    if (isTestToBePerformed) {

      // Set relationship
      MedicalInsurance medInsNew = new MedicalInsurance(99L, "Ameriblast", "B");
      pm.makePersistent(medInsNew);
      emp1.setMedicalInsurance(medInsNew);
      Object medInsNewOid = pm.getObjectId(medInsNew);
      pm.flush();

      // Postcondition
      deferredAssertTrue(
          medInsNew.getEmployee() == emp1,
          ASSERTION_FAILED + testMethod,
          "Postcondition is false; " + "other side of relationship not set on flush.");

      pm.currentTransaction().commit();
      cleanupPM();
      getPM();

      pm.currentTransaction().begin();
      emp1 = (Employee) pm.getObjectById(emp1Oid);
      medInsNew = (MedicalInsurance) pm.getObjectById(medInsNewOid);
      medIns1 = (MedicalInsurance) pm.getObjectById(medIns1Oid);
      deferredAssertTrue(
          medInsNew.getEmployee() == emp1,
          ASSERTION_FAILED + testMethod,
          "Postcondition is false; " + "other side of relationship not set in new pm");
      pm.currentTransaction().commit();

      failOnError();
    }
  }
}
