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

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import jakarta.persistence.EntityManager;
import javax.sql.DataSource;

import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Department;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Employee;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Review;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Before;
import org.junit.Test;

@SuppressWarnings("unchecked")
public class TestUnidirectionalOneToMany extends JPA1Base {

    private static final int EMP_ID_VALUE = 4;
    private static final Integer EMP_ID = Integer.valueOf(EMP_ID_VALUE);
    private static final Set<Pair> SEED_SET = new HashSet<Pair>();
    static {
        SEED_SET.add(new Pair(EMP_ID_VALUE, 1));
        SEED_SET.add(new Pair(EMP_ID_VALUE, 2));
        SEED_SET.add(new Pair(EMP_ID_VALUE, 3));
    }

    @Before
    public void seedDataModel() throws SQLException {
        clearAllTables(); // clear all tables;
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Department dep = new Department(17, "R&D");
            Employee emp = new Employee(EMP_ID_VALUE, "Hans", "Wurst", dep);
            Review r1 = new Review(1, Date.valueOf("2005-10-07"), "bla");
            Review r2 = new Review(2, Date.valueOf("2005-10-08"), "ble");
            Review r3 = new Review(3, Date.valueOf("2005-10-09"), "bli");
            emp.addReview(r1);
            emp.addReview(r2);
            emp.addReview(r3);
            em.persist(dep);
            em.persist(emp);
            em.persist(r1);
            em.persist(r2);
            em.persist(r3);
            env.commitTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testUnchanged() throws SQLException {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            // 1. do nothing
            env.beginTransaction(em);
            Employee emp = em.find(Employee.class, EMP_ID);
            // do nothing
            emp.clearPostUpdate();
            env.commitTransactionAndClear(em);
            verify(!emp.postUpdateWasCalled(), "postUpdate was called");
            checkJoinTable(SEED_SET);
            // 2. touch the reviews
            env.beginTransaction(em);
            emp = em.find(Employee.class, EMP_ID);
            emp.getReviews().size();
            emp.clearPostUpdate();
            env.commitTransactionAndClear(em);
            verify(!emp.postUpdateWasCalled(), "postUpdate was called");
            checkJoinTable(SEED_SET);
            // 3. trivial update
            env.beginTransaction(em);
            emp = em.find(Employee.class, EMP_ID);
            Set<Review> reviews = emp.getReviews();
            emp.setReviews(new HashSet<Review>(reviews));
            emp.clearPostUpdate();
            env.commitTransactionAndClear(em);
            verify(!emp.postUpdateWasCalled(), "postUpdate was called");
            checkJoinTable(SEED_SET);
        } finally {
            closeEntityManager(em);
        }
    }

    private void checkJoinTable(Set<Pair> expected) throws SQLException {
        DataSource ds = getEnvironment().getDataSource();
        Connection conn = ds.getConnection();
        try {
            PreparedStatement pstmt = conn.prepareStatement("SELECT EMP_ID, REVIEW_ID FROM TMP_EMP_REVIEW");
            try {
                ResultSet rs = pstmt.executeQuery();
                try {
                    Set<Pair> actual = new HashSet<Pair>();
                    while (rs.next()) {
                        actual.add(new Pair(rs.getInt("EMP_ID"), rs.getInt("REVIEW_ID")));
                    }
                    verify(expected.size() == actual.size(), "actual set has wrong size " + actual.size() + " expected: "
                            + expected.size());
                    verify(expected.containsAll(actual), "actual set contains some elements missing in the expecetd set");
                    verify(actual.containsAll(expected), "expected set contains some elements missing in the actual set");
                } finally {
                    rs.close();
                }
            } finally {
                pstmt.close();
            }
        } finally {
            conn.close();
        }
    }

    @Test
    public void testDeleteEmployee() throws SQLException {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Employee emp = em.find(Employee.class, EMP_ID);
            verify(emp != null, "employee not found");
            em.remove(emp);
            env.commitTransactionAndClear(em);
            checkJoinTable(new HashSet<Pair>());
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testDeleteReview() throws SQLException {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Employee emp = em.find(Employee.class, EMP_ID);
            verify(emp != null, "employee not found");
            Set reviews = emp.getReviews();
            verify(reviews != null, "reviews are null");
            verify(reviews.size() == 3, "not exactly 3 reviews but " + reviews.size());
            Iterator iter = reviews.iterator();
            Review review = (Review) iter.next();
            int removedId = review.getId();
            // there are no managed relationships -> we have to remove the reviews on both sides
            em.remove(review);
            iter.remove();
            emp.clearPostUpdate();
            env.commitTransactionAndClear(em);
            verify(emp.postUpdateWasCalled(), "post update was not called");
            Set<Pair> expected = new HashSet<Pair>(SEED_SET);
            expected.remove(new Pair(EMP_ID_VALUE, removedId));
            checkJoinTable(expected);
            env.beginTransaction(em);
            emp = em.find(Employee.class, EMP_ID);
            reviews = emp.getReviews();
            verify(reviews.size() == 2, "not exactly 2 reviews but " + reviews.size());
            Object object = em.find(Review.class, Integer.valueOf(removedId));
            verify(object == null, "review found");
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testAdd() throws SQLException {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Employee emp = em.find(Employee.class, EMP_ID);
            verify(emp != null, "employee not found");
            Set<Review> reviews = emp.getReviews();
            Review r4 = new Review(4, Date.valueOf("2005-10-10"), "blo");
            em.persist(r4);
            reviews.add(r4);
            emp.clearPostUpdate();
            env.commitTransactionAndClear(em);
            verify(emp.postUpdateWasCalled(), "post update was not called");
            Set<Pair> expected = new HashSet<Pair>(SEED_SET);
            expected.add(new Pair(EMP_ID_VALUE, 4));
            checkJoinTable(expected);
            env.beginTransaction(em);
            emp = em.find(Employee.class, EMP_ID);
            reviews = emp.getReviews();
            verify(reviews.size() == 4, "not exactly 4 reviews but " + reviews.size());
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testExchange() throws SQLException {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Employee emp = em.find(Employee.class, EMP_ID);
            verify(emp != null, "employee not found");
            Set<Review> reviews = emp.getReviews();
            Iterator iter = reviews.iterator();
            Review review = (Review) iter.next();
            int removedId = review.getId();
            // there are no managed relationships -> we have to remove the reviews on both sides
            em.remove(review);
            iter.remove();
            Review r4 = new Review(4, Date.valueOf("2005-10-10"), "blo");
            em.persist(r4);
            reviews.add(r4);
            emp.clearPostUpdate();
            env.commitTransactionAndClear(em);
            verify(emp.postUpdateWasCalled(), "post update was not called");
            Set<Pair> expected = new HashSet<Pair>(SEED_SET);
            expected.remove(new Pair(EMP_ID_VALUE, removedId));
            expected.add(new Pair(EMP_ID_VALUE, 4));
            checkJoinTable(expected);
            env.beginTransaction(em);
            emp = em.find(Employee.class, EMP_ID);
            reviews = emp.getReviews();
            verify(reviews.size() == 3, "not exactly 3 reviews but " + reviews.size());
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testMoveAllReviews() throws SQLException {
        JPAEnvironment env = getEnvironment();
        EntityManager em = env.getEntityManager();
        try {
            final int newId = 15;
            env.beginTransaction(em);
            Employee emp = em.find(Employee.class, EMP_ID);
            verify(emp != null, "employee not found");
            Set<Review> reviews = emp.getReviews();
            Employee newEmp = new Employee(newId, "Paulchen", "M\u00fcller", null);
            newEmp.setReviews(reviews);
            emp.setReviews(null);
            em.persist(newEmp);
            emp.clearPostUpdate();
            env.commitTransactionAndClear(em);
            verify(emp.postUpdateWasCalled(), "post update was not called");
            Set<Pair> expected = new HashSet<Pair>();
            expected.add(new Pair(newId, 1));
            expected.add(new Pair(newId, 2));
            expected.add(new Pair(newId, 3));
            checkJoinTable(expected);
            env.beginTransaction(em);
            emp = em.find(Employee.class, Integer.valueOf(newId));
            reviews = emp.getReviews();
            verify(reviews.size() == 3, "not exactly 3 reviews but " + reviews.size());
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    private static class Pair {
        /*
         * (non-Javadoc)
         *
         * @see java.lang.Object#equals(java.lang.Object)
         */
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Pair) {
                Pair other = (Pair) obj;
                return other.empId == empId && other.reviewId == reviewId;
            }
            return false;
        }

        /*
         * (non-Javadoc)
         *
         * @see java.lang.Object#hashCode()
         */
        @Override
        public int hashCode() {
            return empId + 17 * reviewId;
        }

        /**
         * @return Returns the empId.
         */
        @SuppressWarnings("unused")
        public int getEmpId() {
            return empId;
        }

        /**
         * @return Returns the reviewId.
         */
        @SuppressWarnings("unused")
        public int getReviewId() {
            return reviewId;
        }

        final int empId;
        final int reviewId;

        Pair(int e, int r) {
            empId = e;
            reviewId = r;
        }
    }
}
