/*
 * Copyright (c) 2005, 2020 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.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;

import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.framework.wdf.ToBeInvestigated;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Bicycle;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.DirtyCar;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Vehicle;
import org.eclipse.persistence.testing.models.wdf.jpa1.island.Island;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Ignore;
import org.junit.Test;

public class SimpleInheritanceTest extends JPA1Base {

    private void verifyExistenceOnDatabase(Short vehicleId) throws SQLException {
        Connection conn = getEnvironment().getDataSource().getConnection();
        try {
            PreparedStatement stmt = conn.prepareStatement("select ID from TMP_VEHICLE where ID = ?");
            try {
                stmt.setShort(1, vehicleId.shortValue());
                ResultSet rs = stmt.executeQuery();
                try {
                    verify(rs.next(), "no department with id " + vehicleId + " found using JDBC.");
                } finally {
                    rs.close();
                }
            } finally {
                stmt.close();
            }
        } finally {
            conn.close();
        }
    }

    private void verifyDiscrminiatorOnDatabase(Short vehicleId, int discriminator) throws SQLException {
        Connection conn = getEnvironment().getDataSource().getConnection();
        try {
            PreparedStatement stmt = conn.prepareStatement("select ID, DTYPE from TMP_VEHICLE where ID = ?");
            try {
                stmt.setShort(1, vehicleId.shortValue());
                ResultSet rs = stmt.executeQuery();
                try {
                    verify(rs.next(), "no department with id " + vehicleId + " found using JDBC.");
                    int actual = rs.getInt(2);
                    verify(discriminator == actual, "wrong discrminiator value: " + actual);
                } finally {
                    rs.close();
                }
            } finally {
                stmt.close();
            }
        } finally {
            conn.close();
        }
    }

    @Test
    public void testInsertVehicle() throws SQLException {
        clearAllTables();
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Vehicle vehicle = new Vehicle();
            vehicle.setBrand("Deutz");
            vehicle.setColor("green");
            em.persist(vehicle);
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(vehicle.getId());
            verifyDiscrminiatorOnDatabase(vehicle.getId(), -1);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testInsertBicycle() throws SQLException {
        clearAllTables();
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Bicycle bicycle = new Bicycle();
            bicycle.setBrand("Peugeot");
            bicycle.setColor("red");
            bicycle.setNumberOfGears((short) 12);
            em.persist(bicycle);
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(bicycle.getId());
            verifyDiscrminiatorOnDatabase(bicycle.getId(), 4);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testFindVehicle() throws SQLException {
        clearAllTables();
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Vehicle vehicle = new Vehicle();
            vehicle.setBrand("Deutz");
            vehicle.setColor("green");
            em.persist(vehicle);
            Short deutzId = vehicle.getId();
            Bicycle bicycle = new Bicycle();
            bicycle.setBrand("Peugeot");
            bicycle.setColor("red");
            bicycle.setNumberOfGears((short) 12);
            em.persist(bicycle);
            env.commitTransactionAndClear(em);
            Short peugeotId = bicycle.getId();
            vehicle = em.find(Vehicle.class, deutzId);
            verify(vehicle.getClass() == Vehicle.class, "wrong class: " + vehicle.getClass());
            vehicle = em.find(Vehicle.class, peugeotId);
            verify(vehicle.getClass() == Bicycle.class, "wrong class: " + vehicle.getClass());
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @ToBeInvestigated
    public void testInsertDirtyCar() throws SQLException {
        clearAllTables();
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            DirtyCar dirtyCar = new DirtyCar();
            dirtyCar.setBrand("VW");
            dirtyCar.setModel("Passat");
            dirtyCar.setColor("yellow");
            dirtyCar.setLicensePlateNumber("DIT-TY 5117");
            em.persist(dirtyCar);
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(dirtyCar.getId());
            verifyDiscrminiatorOnDatabase(dirtyCar.getId(), 71);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testSelectAll() throws SQLException {
        clearAllTables();
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Vehicle vehicle = new Vehicle();
            vehicle.setBrand("Deutz");
            vehicle.setColor("green");
            em.persist(vehicle);
            Short deutzId = vehicle.getId();
            Bicycle bicycle = new Bicycle();
            bicycle.setBrand("Peugeot");
            bicycle.setColor("red");
            bicycle.setNumberOfGears((short) 12);
            em.persist(bicycle);
            env.commitTransactionAndClear(em);
            Short peugeotId = bicycle.getId();
            Query query = em.createQuery("select v from Vehicle v");
            List<?> resultList = query.getResultList();
            verify(resultList.size() == 2, "result list has wrong size");
            for (Object object : resultList) {
                if (object instanceof Vehicle) {
                    Vehicle anyVehicle = (Vehicle) object;
                    if (deutzId.equals(anyVehicle.getId())) {
                        verify(anyVehicle.getClass() == Vehicle.class, "vehicle has unexpected class: "
                                + anyVehicle.getClass().getName());
                    } else if (peugeotId.equals(anyVehicle.getId())) {
                        verify(anyVehicle.getClass() == Bicycle.class, "bicycle has unexpected class: "
                                + anyVehicle.getClass().getName());
                    } else {
                        flop("vehicle has unexpected id: " + anyVehicle.getId());
                    }
                } else {
                    flop("object has unexpected type: " + object.getClass().getName());
                }
            }
            vehicle = em.find(Vehicle.class, deutzId);
            verify(vehicle.getClass() == Vehicle.class, "wrong class: " + vehicle.getClass());
            vehicle = em.find(Vehicle.class, peugeotId);
            verify(vehicle.getClass() == Bicycle.class, "wrong class: " + vehicle.getClass());
        } finally {
            closeEntityManager(em);
        }
    }

    @Ignore
    // TODO fix model
    @Test
    public void testPseudoInheritance() throws SQLException {
        clearAllTables();
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        Connection con = getEnvironment().getDataSource().getConnection();
        try {
            env.beginTransaction(em);
            Island island = new Island("Neufuenfland");
            em.persist(island);
            env.commitTransactionAndClear(em);
            int id = island.getId();
            Statement stmt = con.createStatement();
            try {
                ResultSet rs = stmt.executeQuery("select DTYPE from TMP_ISLAND where ID = " + id);
                try {
                    rs.next();
                    String discriminator = rs.getString(1);
                    verify(discriminator != null, "no discriminator");
                    if (discriminator != null) {
                        verify(discriminator.equals("Island"), "wrong discriminator " + discriminator);
                    }
                } finally {
                    rs.close();
                }
            } finally {
                stmt.close();
            }
        } finally {
            closeEntityManager(em);
            con.close();
        }
    }
}
