/*
 * 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.oxm.mappings.onetomany.keyontarget.eis.nestedownedtoexternalroot;

import java.util.ArrayList;
import java.util.Vector;

import junit.framework.TestCase;
import org.eclipse.persistence.eis.interactions.XQueryInteraction;
import org.eclipse.persistence.internal.eis.adapters.xmlfile.XMLFileInteractionSpec;
import org.eclipse.persistence.testing.oxm.mappings.EISMappingTestCases;
import org.eclipse.persistence.testing.oxm.mappings.onetomany.keyontarget.*;

public class NestedOwnedToExternalRootTestCases extends EISMappingTestCases {
    private final static String XML_RESOURCE = "org/eclipse/persistence/testing/oxm/mappings/onetomany/keyontarget/eis/nestedownedtoexternalroot/writing/company_control.xml";
    private final static String XML_TEST_RESOURCE = "org/eclipse/persistence/testing/oxm/mappings/onetomany/keyontarget/eis/nestedownedtoexternalroot/writing/company.xml";
    private final static String CONTROL_EMPLOYEE1_NAME = "Jane";
    private final static String CONTROL_EMPLOYEE2_NAME = "Bob";
    private final static long CONTROL_PROJECT1_ID = 1;
    private final static String CONTROL_PROJECT1_NAME = "Project1";
    private final static long CONTROL_PROJECT2_ID = 2;
    private final static String CONTROL_PROJECT2_NAME = "Project2";
    private final static long CONTROL_PROJECT3_ID = 3;
    private final static String CONTROL_PROJECT3_NAME = "Project3";

    public NestedOwnedToExternalRootTestCases(String name) throws Exception {
        super(name);
        setControlDocument(XML_RESOURCE);
        setProject(new NestedOwnedToExternalRootProject());
    }

    @Override
    protected Object getControlObject() {
        ArrayList objects = new ArrayList();

        Company company = new Company();
        company.setName("SomeCompany");

        Department dept = new Department();
        dept.setDeptName("TheDepartment");

        //Team team = new Team();
        Project project1 = new Project();
        project1.setId(CONTROL_PROJECT1_ID);
        project1.setName(CONTROL_PROJECT1_NAME);

        Project project2 = new Project();
        project2.setId(CONTROL_PROJECT2_ID);
        project2.setName(CONTROL_PROJECT2_NAME);

        Project project3 = new Project();
        project3.setId(CONTROL_PROJECT3_ID);
        project3.setName(CONTROL_PROJECT3_NAME);

        Employee employee1 = new Employee();
        employee1.setFirstName(CONTROL_EMPLOYEE1_NAME);
        employee1.addProject(project3);

        Employee employee2 = new Employee();
        employee2.setFirstName(CONTROL_EMPLOYEE2_NAME);
        employee2.addProject(project2);

        //team.addEmployee(employee1);
        //team.addEmployee(employee2);
        //team.addProject(project1);
        //team.addProject(project2);
        //team.addProject(project3);
        //return team;
        // return employee1;
        dept.addEmployee(employee1);
        dept.addEmployee(employee2);
        company.addDepartment(dept);

        //return company;
        objects.add(company);
        objects.add(project1);
        objects.add(project2);
        objects.add(project3);

        return objects;
    }

    @Override
    protected ArrayList getRootClasses() {
        ArrayList classes = new ArrayList();
        classes.add(Company.class);
        classes.add(Project.class);
        return classes;
    }

    @Override
    protected Class getSourceClass() {
        return Company.class;
    }

    @Override
    protected String getTestDocument() {
        return XML_TEST_RESOURCE;
    }

    @Override
    protected void createTables() {
        // Drop tables
        XQueryInteraction interaction = new XQueryInteraction();
        XMLFileInteractionSpec spec = new XMLFileInteractionSpec();

        interaction = new XQueryInteraction();
        interaction.setFunctionName("drop-PROJECT");
        spec = new XMLFileInteractionSpec();
        spec.setFileName("project.xml");
        spec.setInteractionType(XMLFileInteractionSpec.DELETE);
        interaction.setInteractionSpec(spec);
        session.executeNonSelectingCall(interaction);

        interaction = new XQueryInteraction();
        interaction.setFunctionName("drop-COMPANY");
        spec = new XMLFileInteractionSpec();
        spec.setFileName("company.xml");
        spec.setInteractionType(XMLFileInteractionSpec.DELETE);
        interaction.setInteractionSpec(spec);
        session.executeNonSelectingCall(interaction);
    }

    @Override
    public void testXMLDocumentToObject() throws Exception {
        updateProjectForReading();

        Vector objects = new Vector();
        for (int i = 0; i < getRootClasses().size(); i++) {
            objects.addAll(session.readAllObjects((Class)getRootClasses().get(i)));
        }

        log("**testXMLDocumentToObject**");
        log("****Expected:");
        log(getControlObject().toString());
        log("***Actual:");
        assertTrue(objects.size() == 4);
        log(objects.toString());
        assertTrue(((java.util.ArrayList)getControlObject()).size() == objects.size());
        ArrayList control = (ArrayList)getControlObject();
        assertEquals(control.get(0), objects.elementAt(0));
        Company company = (Company)objects.get(0);
        Department dept = (Department)company.getDepartments().get(0);
        Vector emps = dept.getEmployees();
        for (int i = 0; i < emps.size(); i++) {
            Employee emp = (Employee)emps.get(i);
            String name = emp.getFirstName();
            Vector projects = emp.getProjects();
            if (name.equalsIgnoreCase(CONTROL_EMPLOYEE1_NAME)) {
                assertEquals(projects.size(), 1);
                Project p = (Project)projects.get(0);
                assertEquals(p.getName(), CONTROL_PROJECT3_NAME);
                assertEquals(p.getId(), CONTROL_PROJECT3_ID);
            } else if (name.equalsIgnoreCase(CONTROL_EMPLOYEE2_NAME)) {
                assertEquals(projects.size(), 1);
                Project p = (Project)projects.get(0);
                assertEquals(p.getName(), CONTROL_PROJECT2_NAME);
                assertEquals(p.getId(), CONTROL_PROJECT2_ID);
            }
        }
    }
}
