/*
 * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2005, 2015 SAP. 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:
//     SAP - initial API and implementation

package org.eclipse.persistence.testing.tests.wdf.jpa1.inheritance;

import java.lang.annotation.Annotation;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreRemove;

import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Bicycle;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.BikeListener;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.CallbackEventListener;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.MountainBike;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Vehicle;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.VehicleListener;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

public class CallbackTest extends JPA1Base {

    private final MyCallbackEventListener listener = new MyCallbackEventListener();
    private final Map<Class<? extends Annotation>, Bicycle> expectedBikeEvent = new HashMap<Class<? extends Annotation>, Bicycle>();
    private final Map<Class<? extends Annotation>, Vehicle> expectedVehicleEvent = new HashMap<Class<? extends Annotation>, Vehicle>();

    private static final class MyCallbackEventListener implements CallbackEventListener {
        private final List<String> log = new ArrayList<String>();
        private Object expectedEntity;
        private int callCounter;
        private Class<? extends Annotation> expectedEvent;

        public void prepare(final Object entity, final Class<? extends Annotation> event) {
            expectedEntity = entity;
            expectedEvent = event;
            log.clear();
            callCounter = 0;
        }

        @Override
        public void callbackCalled(Object entity, Class<? extends Annotation> event) {
            if (event != expectedEvent) {
                log.add("Wrong event, expected " + expectedEvent + ", got " + event);
            }
            if (entity != expectedEntity) {
                log.add("Wrong object, expected " + expectedEntity + ", got " + entity);
            }
            callCounter++;
        }

        public List<String> getLog() {
            return log;
        }

        public int getCallCounter() {
            return callCounter;
        }
    }

    public void bikeCallbackCalled(final Bicycle bike, Class<? extends Annotation> event) {
        if (null == expectedBikeEvent.get(event)) {
            flop("Unexpected event " + event);
            return;
        }
        final Bicycle expectedBike = expectedBikeEvent.remove(event);
        verify(expectedBike == bike, "Unexpected Bike in event " + event + ". Expected: " + expectedBike + ", but got: " + bike);
    }

    public void vehicleCallbackCalled(final Vehicle vehicle, Class<? extends Annotation> event) {
        if (null == expectedVehicleEvent.get(event)) {
            flop("Unexpected event " + event);
            return;
        }
        final Vehicle expectedVehicle = expectedVehicleEvent.remove(event);
        verify(expectedVehicle == vehicle, "Unexpected Vehicle in event " + event + ". Expected: " + expectedVehicle
                + ", but got: " + vehicle);
    }

    @Test
    public void testPrePersist() throws SQLException {
        clearAllTables();
        final JPAEnvironment environment = getEnvironment();
        final EntityManager em = environment.getEntityManager();
        try {
            VehicleListener.setListener(new CallbackEventListener() {
                @Override
                public void callbackCalled(Object entity, Class<? extends Annotation> event) {
                    vehicleCallbackCalled((Vehicle) entity, event);
                }
            });
            try {
                BikeListener.setListener(new CallbackEventListener() {
                    @Override
                    public void callbackCalled(Object entity, Class<? extends Annotation> event) {
                        bikeCallbackCalled((Bicycle) entity, event);
                    }
                });
                try {
                    environment.beginTransaction(em);
                    final Vehicle vehicle = new Vehicle();
                    vehicle.setBrand("Mercedes");
                    vehicle.setColor("cobalt blue");
                    expectedVehicleEvent.put(PrePersist.class, vehicle);
                    em.persist(vehicle);
                    verify(expectedVehicleEvent.size() == 0, "Missing call to prepersist.");
                    final Bicycle bicycle = new Bicycle();
                    bicycle.setBrand("Peugeot");
                    bicycle.setColor("red");
                    bicycle.setNumberOfGears((short) 12);
                    expectedVehicleEvent.put(PrePersist.class, bicycle);
                    listener.prepare(bicycle, PrePersist.class);
                    bicycle.registerListener(listener);
                    try {
                        em.persist(bicycle);
                    } finally {
                        bicycle.registerListener(null);
                    }
                    verify(listener.getCallCounter() == 1, "Missing call to entity callback.");
                    for (final String errorMessage : listener.getLog()) {
                        flop(errorMessage);
                    }
                    verify(expectedVehicleEvent.size() == 0, "Missing call to prepersist.");
                    final MountainBike mountainBike = new MountainBike();
                    mountainBike.setBrand("Fischer");
                    mountainBike.setColor("brown");
                    mountainBike.setNumberOfGears((short) 24);
                    expectedBikeEvent.put(PrePersist.class, mountainBike);
                    expectedVehicleEvent.put(PrePersist.class, mountainBike);
                    listener.prepare(mountainBike, PrePersist.class);
                    mountainBike.registerListener(listener);
                    try {
                        em.persist(mountainBike);
                    } finally {
                        mountainBike.registerListener(null);
                    }
                    verify(listener.getCallCounter() == 1, "Missing call to entity callback.");
                    for (final String errorMessage : listener.getLog()) {
                        flop(errorMessage);
                    }
                    verify(expectedVehicleEvent.size() == 0, "Missing call to prepersist.");
                    verify(expectedBikeEvent.size() == 0, "Missing call to prepersist.");
                } finally {
                    BikeListener.setListener(null);
                }
            } finally {
                VehicleListener.setListener(null);
            }
            environment.commitTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testPreRemove() throws SQLException {
        clearAllTables();
        final JPAEnvironment environment = getEnvironment();
        final EntityManager em = environment.getEntityManager();
        try {
            // persist test entities (without listening to callbacks)
            environment.beginTransaction(em);
            final Vehicle vehicle = new Vehicle();
            vehicle.setBrand("Mercedes");
            vehicle.setColor("cobalt blue");
            em.persist(vehicle);
            final Bicycle bicycle = new Bicycle();
            bicycle.setBrand("Peugeot");
            bicycle.setColor("red");
            bicycle.setNumberOfGears((short) 12);
            em.persist(bicycle);
            final MountainBike mountainBike = new MountainBike();
            mountainBike.setBrand("Fischer");
            mountainBike.setColor("brown");
            mountainBike.setNumberOfGears((short) 24);
            em.persist(mountainBike);
            environment.commitTransactionAndClear(em);
            environment.beginTransaction(em);
            // find the entities right now (before registering listeners)
            final Vehicle storedVehicle = em.find(Vehicle.class, vehicle.getId());
            final Bicycle storedBicycle = em.find(Bicycle.class, bicycle.getId());
            final MountainBike storedMountainBike = (MountainBike) em.find(Vehicle.class, mountainBike.getId());
            // test starts here
            VehicleListener.setListener(new CallbackEventListener() {
                @Override
                public void callbackCalled(Object entity, Class<? extends Annotation> event) {
                    vehicleCallbackCalled((Vehicle) entity, event);
                }
            });
            try {
                BikeListener.setListener(new CallbackEventListener() {
                    @Override
                    public void callbackCalled(Object entity, Class<? extends Annotation> event) {
                        bikeCallbackCalled((Bicycle) entity, event);
                    }
                });
                try {
                    expectedVehicleEvent.put(PreRemove.class, storedVehicle);
                    em.remove(storedVehicle);
                    verify(expectedVehicleEvent.size() == 0, "Missing call to preremove.");
                    expectedVehicleEvent.put(PreRemove.class, storedBicycle);
                    listener.prepare(storedBicycle, PreRemove.class);
                    storedBicycle.registerListener(listener);
                    try {
                        em.remove(storedBicycle);
                    } finally {
                        storedBicycle.registerListener(null);
                    }
                    verify(listener.getCallCounter() == 1, "Missing call to entity callback.");
                    for (final String errorMessage : listener.getLog()) {
                        flop(errorMessage);
                    }
                    verify(expectedVehicleEvent.size() == 0, "Missing call to prepersist.");
                    expectedBikeEvent.put(PreRemove.class, storedMountainBike);
                    expectedVehicleEvent.put(PreRemove.class, storedMountainBike);
                    listener.prepare(storedMountainBike, PreRemove.class);
                    storedMountainBike.registerListener(listener);
                    try {
                        em.remove(storedMountainBike);
                    } finally {
                        storedMountainBike.registerListener(null);
                    }
                    verify(listener.getCallCounter() == 1, "Missing call to entity callback.");
                    for (final String errorMessage : listener.getLog()) {
                        flop(errorMessage);
                    }
                    verify(expectedVehicleEvent.size() == 0, "Missing call to prepersist.");
                    verify(expectedBikeEvent.size() == 0, "Missing call to prepersist.");
                } finally {
                    BikeListener.setListener(null);
                }
            } finally {
                VehicleListener.setListener(null);
            }
            environment.commitTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }
}
