/*
 * 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.workbenchintegration;

import java.util.Comparator;
import java.util.TreeSet;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.testing.framework.TestCase;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.models.collections.Location;
import org.eclipse.persistence.testing.models.employee.domain.Employee;
import org.eclipse.persistence.testing.models.employee.relational.EmployeeProject;
import org.eclipse.persistence.sessions.factories.XMLProjectReader;
import org.eclipse.persistence.sessions.factories.XMLProjectWriter;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.SortedCollectionContainerPolicy;


/*
 * Note, this test not intent to verify the function for the sorted collectionMapping.
 * it just test whether sorted collection mapping with specified comparator
 * can be written to or read from project.xml correctly.
 */
public class ProjectXMLSortedCollectionMapping extends TestCase {
    protected static final String TEMP_FILE = "TempProjectSafeToDelete.xml";
    protected Exception exception = null;

    protected Project readBackProject;

    public ProjectXMLSortedCollectionMapping() {
        setDescription("Tests sorted collection mapping with specified comparator can be written to or read from project XML correctly.");
    }

    @Override
    public void reset() {
    }

    @Override
    public void setup() {
    }

    @Override
    public void test() {
        try{
            Project writeToProject = new EmployeeProject();

            ClassDescriptor descriptorToModify = writeToProject.getDescriptors().get(Employee.class);
            DatabaseMapping mappingToModify = descriptorToModify.getMappingForAttributeName("projects");

            if (mappingToModify.isForeignReferenceMapping()) {
                if (mappingToModify.isCollectionMapping()) {
                    CollectionMapping collectionMapping = (CollectionMapping) mappingToModify;
                    collectionMapping.useSortedSetClassName(TreeSet.class.getName(),getComparator().getName());
                }
            }else{
                throw new Exception("The test must have sorted collection mapping specified in the class descriptor in order to test.");
            }

            // Write out the project with changes and read back in again.
            XMLProjectWriter.write(TEMP_FILE, writeToProject);
            readBackProject = XMLProjectReader.read(TEMP_FILE, getClass().getClassLoader());
        }catch(Exception e){
            exception = e;
        }
    }

    @Override
    protected void verify() {
        if (exception != null){
            throw new TestErrorException("There is problem when read project back from project.xml",exception);
        }
        ClassDescriptor readBackDescriptor = readBackProject.getDescriptors().get(Employee.class);
        DatabaseMapping readBackMapping = readBackDescriptor.getMappingForAttributeName("projects");
        CollectionMapping collectionMapping = (CollectionMapping)readBackMapping;
        ContainerPolicy containerPolciy = collectionMapping.getContainerPolicy();
        if(containerPolciy.isCollectionPolicy()){
            Class conatinerClass = containerPolciy.getContainerClass();
            Class comparatorClass = ((SortedCollectionContainerPolicy)containerPolciy).getComparatorClass();
            if(!conatinerClass.equals(TreeSet.class) ){
                throw new TestErrorException("The container class read was not equal to the conatiner class set originally, which expected as the java.util.TreeSet class. ");
            }
            if(!comparatorClass.equals(ProjectXMLSortedCollectionMapping.ProjectComparator.class)){
                throw new TestErrorException("The comparator class read was not equal to the comparator class set originally, which expected as the ProjectXMLCollectionMappingUseSortedClassNameTest.ProjectComparator class. ");
            }
        }else{
            throw new TestErrorException("The container policy expect to set as SortedCollectionContainerPolicy.");
        }
    }

    public Class getComparator(){
        return ProjectXMLSortedCollectionMapping.ProjectComparator.class;
    }

    public static class ProjectComparator implements Comparator{
        @Override
        public int compare(Object object1, Object object2) {
            if ((object1.getClass() != Project.class) || (object2.getClass() != Project.class)) {
                throw new ClassCastException("Invalid comparison : " + object1 + ", " + object2);
            }
            Location loc1 = (Location)object1;
            Location loc2 = (Location)object2;
            return String.CASE_INSENSITIVE_ORDER.compare(loc1.getArea(), loc2.getArea());
        }
    }

}
