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

import java.util.Calendar;
import java.util.Date;
import javax.jdo.JDOHelper;
import javax.jdo.Query;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.company.Address;
import org.apache.jdo.tck.pc.company.Company;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Projected Second Class Objects Do Not Track Their Changes <br>
 * <B>Keywords:</B> embedded query <br>
 * <B>Assertion ID:</B> A14.6.9-9. <br>
 * <B>Assertion Description: </B> If an SCO field is in the result, the projected field is not owned
 * by any persistent instance, and modifying the SCO value has no effect on any persistent instance.
 * If an FCO field is in the result, the projected field is a persistent instance, and modifications
 * made to the instance are reflected as changes to the datastore per transaction requirements.
 */
public class ProjectedSCODoesNotTrackChanges extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertion A14.6.9-3 (ProjectedSCODoesNotTrackChanges) failed: ";

  private static final Date expectedDate;

  static {
    Calendar cal = Calendar.getInstance();
    cal.set(1970, 0, 1, 0, 0, 0);
    cal.set(Calendar.MILLISECOND, 0);
    expectedDate = cal.getTime();
  }

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

  /**
   * @see org.apache.jdo.tck.JDO_Test#localSetUp()
   */
  @Override
  protected void localSetUp() {
    addTearDownClass(Company.class);
  }

  private Company getPersistentNewInstance(long companyid) {
    Company obj =
        new Company(companyid, "MyCompany", expectedDate, new Address(0, "", "", "", "", ""));
    pm.makePersistent(obj); // obj should transition to persistent-new
    int curr = currentState(obj);
    if (curr != PERSISTENT_NEW) {
      fail(
          ASSERTION_FAILED,
          "Unable to create persistent-new instance "
              + "from transient instance via makePersistent(), state is "
              + states[curr]);
    }
    return obj;
  }

  /**
   * This tests that when an embedded field is selected and modified, there is no change in the
   * owned instance.
   */
  public void testEmbeddedField() {
    String testZip = "94040";
    pm = getPM();
    pm.currentTransaction().begin();
    Company comp = getPersistentNewInstance(0);
    pm.currentTransaction().commit();

    // Select address, modify, and commit
    pm.currentTransaction().begin();
    Query<Company> query = pm.newQuery(Company.class, "name.startsWith(\"MyCompany\")");
    query.setResult("address");
    query.setUnique(true);
    Address myCompanyAddress = (Address) query.execute();
    myCompanyAddress.setZipcode(testZip);
    if (JDOHelper.isDirty(comp)) {
      appendMessage(
          "Expected Company instance not to be dirty; "
              + "actual state is "
              + getStateOfInstance(comp));
    }
    pm.currentTransaction().commit();

    // Check value of address
    pm.currentTransaction().begin();
    Address persistedCompanyAddress = (Address) query.execute();
    String actualZip = persistedCompanyAddress.getZipcode();
    if (actualZip.equals(testZip)) {
      appendMessage(
          "Expected projected field value is " + testZip + "; actual value is " + actualZip);
    }
    logger.debug("MyCompany's zipcode is '" + actualZip + "'");
    pm.currentTransaction().commit();
    failOnError();
  }

  /**
   * This tests that when a Date field is selected and modified, there is no change in the owned
   * instance.
   */
  public void testDateField() {
    pm = getPM();
    pm.currentTransaction().begin();
    Company comp = getPersistentNewInstance(0);
    pm.currentTransaction().commit();

    // Select date, modify, and commit
    pm.currentTransaction().begin();
    Query<Company> query = pm.newQuery(Company.class, "name.startsWith(\"MyCompany\")");
    query.setResult("founded");
    query.setUnique(true);
    Date retrievedDate = (Date) query.execute();
    retrievedDate.setTime(123789L);

    if (JDOHelper.isDirty(comp)) {
      appendMessage(
          "Expected Company instance not to be dirty; "
              + "actual state is "
              + getStateOfInstance(comp));
    }
    pm.currentTransaction().commit();

    // Check value of date
    pm.currentTransaction().begin();
    Date actualDate = (Date) query.execute();
    if (!actualDate.equals(expectedDate)) {
      appendMessage(
          "Expected projected field value is "
              + expectedDate
              + "; actual value is "
              + actualDate
              + "; modified retrieved value is "
              + retrievedDate);
    }
    logger.debug("MyCompany's founded date is '" + actualDate + "'");
    pm.currentTransaction().commit();
    failOnError();
  }
}
