/*
 * Copyright (c) 2011, 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:
// dmccann - August 5/2010 - 2.2 - Initial implementation
package org.eclipse.persistence.testing.jaxb.externalizedmetadata.multiplebindings;

import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.testing.jaxb.JAXBWithJSONTestCases;
import org.eclipse.persistence.testing.jaxb.externalizedmetadata.multiplebindings.simple.Department;
import org.eclipse.persistence.testing.jaxb.externalizedmetadata.multiplebindings.simple.Employee;
import org.eclipse.persistence.testing.jaxb.externalizedmetadata.multiplebindings.simple.Person;
import org.eclipse.persistence.testing.jaxb.externalizedmetadata.multiplebindings.simple.Phone;

public class MultipleBindingsFourFilesTestCases extends JAXBWithJSONTestCases {
      protected final static String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/multiplebindings/fourfilesmultiplebindings.xml";
      protected final static String JSON_RESOURCE = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/multiplebindings/fourfilesmultiplebindings.json";
      XMLDescriptor employeeDesc = null;
        public MultipleBindingsFourFilesTestCases(String name) throws Exception {
            super(name);
        }

        @Override
        public void setUp() throws Exception {
            setControlDocument(XML_RESOURCE);
            setControlJSON(JSON_RESOURCE);
            super.setUp();
            Type[] types = new Type[2];
            types[0] = Person.class;
            types[1] = Employee.class;
            setTypes(types);
        }

        public void init() throws Exception {
            Type[] types = new Type[2];
            types[0] = Person.class;
            types[1] = Employee.class;
            setTypes(types);
        }

        @Override
        protected Object getControlObject() {
            Employee emp = new Employee();
            emp.age = 35;
            emp.id = "someID";
            emp.name = "Bob Jones";
            emp.address = "123 theStreet";
            emp.jobTitle = "job3";

            emp.departments = new ArrayList();
            emp.departments.add(Department.DEV);
            emp.departments.add(Department.SUPPORT);

            Phone phone = new Phone();
            phone.number = "12345678";
            emp.phone = phone;
            return emp;
        }

        public void testSchemaGen() throws Exception {
            List<InputStream> controlSchemas = new ArrayList<InputStream>();
            InputStream is = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/multiplebindings/fourfilesmultiplebindings.xsd");
            //InputStream is2= ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/multiplebindings/fourfilesmultiplebindings2.xsd");
            controlSchemas.add(is);
            //controlSchemas.add(is2);
            super.testSchemaGen(controlSchemas);
        }

        @Override
        protected Map getProperties() {

            Map overrides = new HashMap();


            //DOMSource src1 = null;
            //DOMSource src2 = null;
            StreamSource src1 = null;
            StreamSource src2 = null;
            StreamSource src3 = null;
            StreamSource src4 = null;

            InputStream iStream = classLoader.getResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/multiplebindings/eclipselink-oxm1.xml");
            InputStream iStream2 = classLoader.getResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/multiplebindings/eclipselink-oxm2.xml");
            InputStream iStream3 = classLoader.getResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/multiplebindings/eclipselink-oxm3.xml");
            InputStream iStream4 = classLoader.getResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/multiplebindings/eclipselink-oxm4.xml");
          //  InputStream iStreamCopy = classLoader.getResourceAsStream("eclipselink-oxm1.xml");

            try {
                //Document doc = parser.parse(new ByteArrayInputStream(bindings1.getBytes()));
                //src1 = new DOMSource(doc.getDocumentElement());
                //src2 = new DOMSource(doc.getDocumentElement());
                src1 = new StreamSource(iStream);
                src2 = new StreamSource(iStream2);
                src3 = new StreamSource(iStream3);
                src4 = new StreamSource(iStream4);
            } catch (Exception e) {
                e.printStackTrace();
                fail("An error occurred during setup");
            }

            ArrayList<Object> bindingsList = new ArrayList();
            bindingsList.add(src1);
            bindingsList.add(src2);
            bindingsList.add(src3);
            bindingsList.add(src4);

            overrides.put("org.eclipse.persistence.testing.jaxb.externalizedmetadata.multiplebindings.simple", bindingsList);

            Map props = new HashMap();
            props.put(JAXBContextProperties.OXM_METADATA_SOURCE, overrides);
            return props;
        }



        public void testUserProperties(){
            String PROPKEY_1 ="1";
            String PROPKEY_2 ="2";
            String PROPKEY_3 ="3";

            String PROPVAL_1 ="A";
            Integer PROPVAL_2 =66;
            Boolean PROPVAL_3 =Boolean.TRUE;
            XMLDescriptor employeeDesc =  this.xmlContext.getDescriptor(new QName("", "empRoot4"));

            DatabaseMapping projectNameMapping = employeeDesc.getMappingForAttributeName("id");

            Map props = projectNameMapping.getProperties();

            assertNotNull("No user-defined properties exist on the mapping for [id]", props);

            assertTrue("Expected [3] user-defined properties, but there were [" + props.size() + "]", props.size() == 3);
            // verify entries exist for each key
            assertNotNull("No property found for key [" + PROPKEY_1 + "]", props.get(PROPKEY_1));
            assertNotNull("No property found for key [" + PROPKEY_2 + "]", props.get(PROPKEY_2));
            assertNotNull("No property found for key [" + PROPKEY_3 + "]", props.get(PROPKEY_3));
            // verify value-types
            assertTrue("Expected value-type [String] for key [" + PROPKEY_1 + "] but was [" + props.get(PROPKEY_1).getClass().getName() + "]", props.get(PROPKEY_1) instanceof String);
            assertTrue("Expected value-type [Integer] for key [" + PROPKEY_2 + "] but was [" + props.get(PROPKEY_2).getClass().getName() + "]", props.get(PROPKEY_2) instanceof Integer);
            assertTrue("Expected value-type [Boolean] for key [" + PROPKEY_3 + "] but was [" + props.get(PROPKEY_3).getClass().getName() + "]", props.get(PROPKEY_3) instanceof Boolean);
            // verify values
            assertTrue("Expected property value [" + PROPVAL_1 + "] for key [" + PROPKEY_1 + "] but was [" + props.get(PROPKEY_1) + "]", PROPVAL_1.equals(props.get(PROPKEY_1)));
            assertTrue("Expected property value [" + PROPVAL_2 + "] for key [" + PROPKEY_2 + "] but was [" + props.get(PROPKEY_2) + "]", PROPVAL_2.equals(props.get(PROPKEY_2)));
            assertTrue("Expected property value [" + PROPVAL_3 + "] for key [" + PROPKEY_3 + "] but was [" + props.get(PROPKEY_3) + "]", PROPVAL_3 == props.get(PROPKEY_3));

        }

        public void testDescriptorProperties() {
            // create the JAXBContext
            assertNotNull("JAXBContext creation failed", xmlContext);
            XMLDescriptor xdesc = xmlContext.getDescriptor(new QName("", "empRoot4"));
            assertNotNull("Employee descriptor is null", xdesc);
            assertNotNull("No user-defined properties exist on the descriptor for Employee", xdesc.getProperties());
            Map props = xdesc.getProperties();
            assertEquals(8, props.size());
            assertEquals("I", props.get("2"));
        }

        public void testNamespaceResolver(){
            assertNotNull("JAXBContext creation failed", xmlContext);
            XMLDescriptor xdesc = xmlContext.getDescriptor(new QName("", "empRoot4"));
            assertNotNull("Employee descriptor is null", xdesc);

            // Test merged namespaces
            // Ensure that there are two namespaces for prefix "uriA" and one for "uriB"
            String uriA = "http://www.example.com/uriA";
            String uriB = "http://www.example.com/uriB";

            String prefixA = "prefixA";
            String prefixNewA = "newPrefixA";
            String prefixB = "prefixB";

            assertEquals(uriA, xdesc.getNamespaceResolver().resolveNamespacePrefix(prefixA));
            assertEquals(uriA, xdesc.getNamespaceResolver().resolveNamespacePrefix(prefixNewA));
            assertEquals(uriB, xdesc.getNamespaceResolver().resolveNamespacePrefix(prefixB));
        }

}
