/*
 * Copyright (c) 1998, 2021 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:
//     dminsky - initial API and implementation
package org.eclipse.persistence.testing.tests.optimisticlocking;

import java.util.Iterator;
import java.util.ArrayList;

import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.sessions.UnitOfWork;

import org.eclipse.persistence.testing.framework.TestException;
import org.eclipse.persistence.testing.models.optimisticlocking.Camera;
import org.eclipse.persistence.testing.models.optimisticlocking.Gamer;
import org.eclipse.persistence.testing.models.optimisticlocking.GamesConsole;
import org.eclipse.persistence.testing.models.optimisticlocking.PowerSupplyUnit;

/**
 * Test updating a value from a null DB value to a non-null value and back again.
 * EL bug 319759
 * @author dminsky
 */
public class UpdateNullManyToManyValueTest extends SwitchableOptimisticLockingPolicyTest {

    protected GamesConsole original;
    protected GamesConsole original2;

    public UpdateNullManyToManyValueTest(Class optimisticLockingPolicyClass) {
        super(optimisticLockingPolicyClass);
        addClassToModify(Gamer.class);
        addClassToModify(GamesConsole.class);
    }

    @Override
    public void setup() {
        super.setup();
        UnitOfWork uow = getSession().acquireUnitOfWork();
        original = new GamesConsole("PloughStation4", "black");
        original.setCamera(new Camera("eye", "black"));
        original.setPsu(new PowerSupplyUnit("0-123-456-789"));
        // no gamers

        original2 = new GamesConsole();
        original2.setName("Segone");

        uow.registerObject(original);
        uow.registerObject(original2);
        uow.commit();
    }

    @Override
    public void test() throws TestException {
        try {
            getSession().getIdentityMapAccessor().initializeAllIdentityMaps();

            readObjectAndAddIntoCollection(new Gamer("testy", null), false);
            updateFirstObject();
            readObjectAndAddIntoCollection(new Gamer("t4h_fury", "pwner"), false);
            readObjectAndAddIntoCollection(new Gamer("t5h_fury", null), false);
            readObjectAndAddIntoCollection(new Gamer("t6h_fury", "pwner"), false);
            readObjectAndAddIntoCollection(null, true);
            readObjectAndAddIntoCollection(new Gamer(null, "pwner"), true);
            updateFirstObject();
            readObjectAndAddIntoCollection(new Gamer("t8h_fury", null), false);
            readObjectAndAddIntoCollection(new Gamer("t9h_fury", "pwner"), false);
            readObjectAndAddIntoCollection(null, true);
            readObjectAndAddIntoCollection(new Gamer("10_fury", "pwner"), true);
            updateFirstObject();
            readObjectAndAddIntoCollection(new Gamer(null, "pwner"), true);
            updateFirstObject();
            readObjectAndAddIntoCollection(new Gamer(null, null), true);
            updateFirstObject();
            readObjectAndAddIntoCollection(new Gamer("13_fury", null), true);
            updateFirstObject();
            readObjectAndAddIntoCollection(new Gamer("14_fury", "pwner"), true);
            updateFirstObject();
            readObjectAndAddIntoCollection(null, true);

            // delete the objects
            deleteObject(original);
            deleteObject(original2);
        } catch (Exception tle) {
            this.tlException = tle;
            this.tlException.printStackTrace();
        }
    }

    public void readObjectAndAddIntoCollection(Gamer newGamer, boolean removeAll) {
        UnitOfWork uow = getSession().acquireUnitOfWork();

        GamesConsole clone = (GamesConsole) uow.readObject(
                GamesConsole.class,
            new ExpressionBuilder().get("id").equal(this.original.getId()));

        assertNotNull("The object returned should be not null", clone);

        if (removeAll == true) {
            Iterator<Gamer> gamers = new ArrayList(clone.getGamers()).iterator();
            while (gamers.hasNext()) {
                Gamer g = gamers.next();
                g.setName(null);
                clone.removeGamer(g);
            }
        }

        if (newGamer != null) {
            clone.addGamer(newGamer);
        }

        uow.commit();
    }

    public void updateFirstObject() {
        UnitOfWork uow = getSession().acquireUnitOfWork();

        GamesConsole clone = (GamesConsole) uow.readObject(
                GamesConsole.class,
            new ExpressionBuilder().get("id").equal(this.original.getId()));

        assertNotNull("The object returned should be not null", clone);

        if (!clone.getGamers().isEmpty()) {
            Gamer g = clone.getGamers().get(0);
            g.setDescription(null);
            g.setName(null);
        }

        uow.commit();
    }

    @Override
    public void reset() {
        super.reset();
        this.original = null;
        this.original2 = null;
    }

}

