/*
 * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     12/30/2016-2.7 Tomas Kraus
//       - 490677: Initial API and implementation.
package org.eclipse.persistence.testing.tests.nosql;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import jakarta.persistence.EntityManager;

import org.eclipse.persistence.internal.nosql.adapters.nosql.OracleNoSQLConnection;
import org.eclipse.persistence.testing.models.jpa.nosql.Address;
import org.eclipse.persistence.testing.models.jpa.nosql.LineItem;
import org.eclipse.persistence.testing.models.jpa.nosql.Order;

import oracle.kv.Direction;
import oracle.kv.KVStore;
import oracle.kv.Key;

/**
 * JPA test model helper methods.
 */
public class JPAModelHelper {

    /**
     * Build {@link Address} instance.
     * @return {@link Address} instance.
     */
    public static Address buildAddress() {
        final Address address = new Address();
        address.city = "Ottawa";
        address.addressee = "Bob Jones";
        address.state = "CA";
        address.country = "Mexico";
        address.zipCode = "12345";
        return address;
    }

    /**
     * Build list of {@link LineItem} instances.
     * @return List of {@link LineItem} instances.
     */
    public static List<LineItem> buildLineItemsList() {
        final List<LineItem> lineItems = new ArrayList<>();
        final LineItem line1 = new LineItem();
        line1.itemName = "stuff";
        line1.itemPrice = new BigDecimal("10.99");
        line1.lineNumber = 1;
        line1.quantity = 100;
        lineItems.add(line1);
        final LineItem line2 = new LineItem();
        line2.itemName = "more stuff";
        line2.itemPrice = new BigDecimal("20.99");
        line2.lineNumber = 2;
        line2.quantity = 50;
        lineItems.add(line2);
        return lineItems;
    }

    /**
     * Build {@link Order} instance.
     * @param address {@link Address} instance to be attached.
     * @param lineItems List of {@link LineItem} instances to be attached.
     * @return {@link Order} instance.
     */
    public static Order buildOrder(final Address address, final List<LineItem> lineItems) {
        final Order order = new Order();
        order.orderedBy = "ACME";
        order.comments.add("priority order");
        order.comments.add("next day");
        order.address = address;
        order.lineItems = lineItems;
        return order;
    }

    /**
     * Build data model for tests.
     * @param em    {@link EntityManager} used to access database.
     * @param count Number of {@link Order} instances to store.
     * @return An array of stored {@link Order} instances.
     */
    public static Order[] buildModel(final EntityManager em, final int count) {
        final Order[] orders = new Order[count];
        EntityManagerHelper.beginTransaction(em);
        for (int index = 0; index < count; index++) {
            final Address address = buildAddress();
            final List<LineItem> lineItems = buildLineItemsList();
            final Order order = buildOrder(address, lineItems);
            em.persist(order);
            orders[index] = order;
        }
        EntityManagerHelper.commitTransaction(em);
        return orders;
    }


    /**
     * Delete data model for tests.
     */
    public static void deleteModel(final EntityManager em) {
        EntityManagerHelper.beginTransaction(em);
        final KVStore store = ((OracleNoSQLConnection)em.unwrap(jakarta.resource.cci.Connection.class)).getStore();
        final Iterator<Key> iterator = store.storeKeysIterator(Direction.UNORDERED, 0);
        while (iterator.hasNext()) {
            store.multiDelete(iterator.next(), null, null);
        }
        EntityManagerHelper.commitTransaction(em);
    }

}
