/*
 * 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:
//     Matt MacIvor - 2.4 - initial implementation
package org.eclipse.persistence.testing.jaxb.dynamic.withstatic;

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

import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.internal.dynamic.DynamicEntityImpl;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.UnmarshallerProperties;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
import org.eclipse.persistence.testing.jaxb.JAXBWithJSONTestCases;

public class DynamicWithStaticTestCases extends JAXBWithJSONTestCases {

//    private DynamicJAXBContext jaxbContext;
    private static final String RESOURCE_DIR = "org/eclipse/persistence/testing/jaxb/dynamic/withstatic/";

    // Schema files used to test each feature
    private static final String NO_ADDRESS = RESOURCE_DIR + "noaddress-oxm.xml";
    private static final String CONTROL_DOC = RESOURCE_DIR + "customer1.xml";
    private static final String JSON_CONTROL_DOC = RESOURCE_DIR + "customer1.json";
    private static final String PACKAGE = "org.eclipse.persistence.testing.jaxb.dynamic.withstatic";

    public DynamicWithStaticTestCases(String name) throws Exception {
        super(name);
        setupContext();
        setControlDocument(CONTROL_DOC);
        setControlJSON(JSON_CONTROL_DOC);
    }

    @Override
    public String getName() {
        return "Dynamic JAXB: OXM: " + super.getName();
    }

    @Override
    protected Object getControlObject() {
        DynamicEntity employee = ((DynamicJAXBContext)jaxbContext).newDynamicEntity(PACKAGE + "." + "Customer");
        DynamicEntity phone1 = ((DynamicJAXBContext)jaxbContext).newDynamicEntity(PACKAGE + "." + "PhoneNumber");
        DynamicEntity phone2 = ((DynamicJAXBContext)jaxbContext).newDynamicEntity(PACKAGE + "." + "PhoneNumber");
        phone1.set("value", "555-WORK");
        phone1.set("type", "work");
        phone2.set("value", "555-HOME");
        phone2.set("type", "home");

        ArrayList phones = new ArrayList();
        phones.add(phone1);
        phones.add(phone2);
        employee.set("phoneNumber", phones);

        Address address = new Address();
        address.city = "Any Town";
        address.street = "123 Some Street";

        employee.set("address", address);
        employee.set("name", "Jane Doe");

        return employee;
    }



    void setupContext() throws Exception {
        classLoader = Thread.currentThread().getContextClassLoader();
        InputStream iStream = classLoader.getResourceAsStream(NO_ADDRESS);
        if (iStream == null) {
            fail("Couldn't load metadata file [" + NO_ADDRESS + "]");
        }

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, iStream);

        jaxbContext = DynamicJAXBContextFactory.createContext(PACKAGE, null, properties);
        xmlContext = ((org.eclipse.persistence.jaxb.JAXBContext)jaxbContext).getXMLContext();
        setProject(xmlContext.getSession(0).getProject());
        jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbUnmarshaller = jaxbContext.createUnmarshaller();

        jaxbMarshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, "value");
        jaxbUnmarshaller.setProperty(UnmarshallerProperties.JSON_VALUE_WRAPPER, "value");
    }

    @Override
    public void xmlToObjectTest(Object testObject, Object controlObject) throws Exception {
        log("\n**xmlToObjectTest**");
        log("Expected:");
        log(controlObject.toString());
        log("Actual:");
        log(testObject.toString());

        compareDynamicEntities(testObject, controlObject);
    }

    @Override
    public void jsonToObjectTest(Object testObject) throws Exception {
        log("\n**xmlToObjectTest**");
        log("Expected:");
        log(getReadControlObject().toString());
        log("Actual:");
        log(testObject.toString());
        compareDynamicEntities(testObject, getReadControlObject());
    }

    private void compareDynamicEntities(Object testObject, Object controlObject) {
        if(testObject instanceof DynamicEntity && controlObject instanceof DynamicEntity) {
            DynamicEntity test = (DynamicEntity)testObject;
            DynamicEntity control = (DynamicEntity)controlObject;
            for(String key: ((DynamicEntityImpl)test).getPropertiesMap().keySet()) {
                Object testValue = test.get(key);
                Object controlValue = control.get(key);
                if(testValue instanceof List && controlValue instanceof List) {
                    for(int i = 0; i < ((List)testValue).size(); i++) {
                        Object nextTestValue = ((List)testValue).get(i);
                        Object nextControlValue = ((List)controlValue).get(i);
                        if(nextTestValue instanceof DynamicEntity) {
                            compareDynamicEntities(nextTestValue, nextControlValue);
                        } else {
                            assertEquals(nextTestValue, nextControlValue);
                        }
                    }
                }
                else if(testValue instanceof DynamicEntity) {
                    compareDynamicEntities(testValue, controlValue);
                } else {
                    assertEquals(testValue, controlValue);
                }
            }
        } else {
            assertEquals(testObject, controlObject);
        }

    }
}
