/*
 * 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:
//     Denise Smith - 2.4
package org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlidref;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.testing.jaxb.JAXBWithJSONTestCases;

public class XmlIdRefTestCases extends JAXBWithJSONTestCases{
    private static final String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/xmlidref/root.xml";
    private static final String JSON_RESOURCE = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/xmlidref/root.json";
    public XmlIdRefTestCases(String name) throws Exception {
        super(name);
        setControlDocument(XML_RESOURCE);
        setControlJSON(JSON_RESOURCE);
        setClasses(new Class[] { Employee.class, Address.class, Root.class });
    }

     @Override
     public Map getProperties(){
            InputStream inputStream = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/xmlidref/eclipselink-oxm.xml");

            HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
            metadataSourceMap.put("org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlidref", new StreamSource(inputStream));
            Map<String, Map<String, Source>> properties = new HashMap<String, Map<String, Source>>();
            properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, metadataSourceMap);

            return properties;
        }

      /**
         * Tests @XmlID override via eclipselink-oxm.xml.  Overrides the @XmlID [city]
         * with xml-id [id], and @XmlIDREF [homeAddress] with xml-idref [workAddress].
         *
         * Positive test.
         */
        public void testSchemaGen() throws Exception{
            List controlSchemas = new ArrayList();
            InputStream is = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/xmlidref/schema.xsd");

            controlSchemas.add(is);

            super.testSchemaGen(controlSchemas);


        }

    @Override
    public Object getControlObject() {
        Address home123 = new Address();
        home123.city = "Woodlawn";
        home123.id = "ha123";
        Address work111 = new Address();
        work111.city = "Ottawa";
        work111.id = "wa111";
        Address work112 = new Address();
        work112.city = "Kanata";
        work112.id = "wa112";
        Address work113 = new Address();
        work113.city = "Orleans";
        work113.id = "wa113";
        Employee emp = new Employee();
        emp.name = "Joe Black";
        emp.homeAddress = home123;
        emp.workAddress = work111;
        Root root = new Root();
        root.employees = new ArrayList<Employee>();
        root.addresses = new ArrayList<Address>();
        root.employees.add(emp);
        root.addresses.add(work111);
        root.addresses.add(work112);
        root.addresses.add(work113);
        return root;
    }

    /**
     * Verifies that the primary key [primary-key/@aid] was set correctly
     * on the Address descriptor.
     */
    public void testPrimaryKeyWasSet() {
        XMLDescriptor xdesc = ((JAXBContext) jaxbContext).getXMLContext().getDescriptor(new QName("address"));
        Vector<String> pkFields = xdesc.getPrimaryKeyFieldNames();
        assertTrue("Expected [1] primary key field for Address, but was [" + pkFields.size() + "]", pkFields.size() == 1);
        assertTrue("Expected primary key field [primary-key/@aid] for Address, but was [" + pkFields.elementAt(0) + "]", pkFields.elementAt(0).equals("primary-key/@aid"));
    }


    @Override
    public void xmlToObjectTest(Object testObject) throws Exception {
        super.xmlToObjectTest(testObject);
        Root testRoot = (Root) testObject;
        assertNotNull(testRoot);
        Employee emp = testRoot.employees.get(0);
        assertNotNull(emp);
        Address workAddress = emp.workAddress;
        assertNotNull(workAddress);
        assertNotNull(workAddress.id);
        assertNotNull(workAddress.city);
        assertTrue("Expected work address id [wa111] but was [" + workAddress.id + "]", workAddress.id.equals("wa111"));
        assertTrue("Expected work address city [Ottawa] but was [" + workAddress.city + "]", workAddress.city.equals("Ottawa"));
    }


}
