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

import java.math.BigDecimal;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.fieldtypes.HashSetCollections;
import org.apache.jdo.tck.pc.fieldtypes.SimpleClass;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Support of field type HashSet <br>
 * <B>Keywords:</B> model <br>
 * <B>Assertion ID:</B> A6.4.3-22. <br>
 * <B>Assertion Description: </B> JDO implementations must support fields of the mutable object
 * class <code>java.util.HashSet</code>, and may choose to support them as Second Class Objects or
 * First Class Objects.
 */
public class TestHashSetCollections extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertion A6.4.3-22 (TestHashSetCollections) failed: ";

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

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

  /** */
  public void test() {
    pm = getPM();

    runTest(pm);

    pm.close();
    pm = null;
  }

  /** */
  void runTest(PersistenceManager pm) {
    Transaction tx = pm.currentTransaction();
    HashSetCollections expectedValue = new HashSetCollections();

    // turn on datastore transactions
    tx.setOptimistic(false);
    tx.begin();
    HashSetCollections pi = new HashSetCollections();
    pi.identifier = 1;
    pm.makePersistent(pi);
    Object oid = pm.getObjectId(pi);
    // Provide initial set of values
    setValues(pi, 1);
    tx.commit();

    // cache will be flushed
    pi = null;
    System.gc();

    tx.begin();
    setValues(expectedValue, 1);
    checkValues(oid, expectedValue);
    pi = (HashSetCollections) pm.getObjectById(oid, true);
    // Provide new set of values
    setValues(pi, 2);
    tx.commit();

    // cache will be flushed
    pi = null;
    System.gc();

    tx.begin();
    // check new values
    setValues(expectedValue, 2);
    checkValues(oid, expectedValue);
    pi = (HashSetCollections) pm.getObjectById(oid, true);
    tx.commit();
  }

  /** */
  private void setValues(HashSetCollections collect, int order) {
    Collection<?> value;
    int n = collect.getLength();
    for (int i = 0; i < n; ++i) {
      String valueType = TestUtil.getFieldSpecs(HashSetCollections.fieldSpecs[i]);
      value = TestUtil.makeNewVectorInstance(valueType, order);
      HashSet<?> lvalue = new HashSet<>(value);
      collect.set(i, lvalue);
      if (debug) logger.debug("Set " + i + "th value to: " + value);
    }
  }

  /** */
  private void checkValues(Object oid, HashSetCollections expectedValue) {
    int i;
    StringBuilder sbuf = new StringBuilder();
    HashSetCollections pi = (HashSetCollections) pm.getObjectById(oid, true);
    int n = pi.getLength();
    for (i = 0; i < n; ++i) {
      HashSet<?> expected = expectedValue.get(i);
      HashSet<?> actual = pi.get(i);
      if (actual.size() != expected.size()) {
        sbuf.append(
            "\nFor element "
                + i
                + ", expected size = "
                + expected.size()
                + ", actual size = "
                + actual.size()
                + " . ");
      } else if (!expected.equals(actual)) {
        if (TestUtil.getFieldSpecs(HashSetCollections.fieldSpecs[i]).equals("BigDecimal")) {
          // sort values for comparison
          TreeSet<?> expectedTS = new TreeSet<>(expected);
          TreeSet<?> actualTS = new TreeSet<>(actual);
          Iterator<?> expectedIter = expectedTS.iterator();
          Iterator<?> actualIter = actualTS.iterator();
          for (int j = 0; j < expectedTS.size(); j++) {
            BigDecimal bigDecExpected = (BigDecimal) (expectedIter.next());
            BigDecimal bigDecActual = (BigDecimal) (actualIter.next());
            bigDecActual.setScale(bigDecExpected.scale());
            if ((bigDecExpected.compareTo(bigDecActual)) != 0) {
              sbuf.append(
                  "\nFor element "
                      + i
                      + "("
                      + j
                      + "), expected = "
                      + bigDecExpected
                      + ", actual = "
                      + bigDecActual);
            }
          }
        } else {
          sbuf.append(
              "\nFor element " + i + ", expected = " + expected + ", actual = " + actual + " . ");
        }
      }
    }
    if (sbuf.length() > 0) {
      fail(ASSERTION_FAILED, "Expected and observed do not match!!" + sbuf);
    }
  }
}
