/*
 * 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.JAXBContextProperties;
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 StaticWithDynamicTestCases 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 + "address-with-phone-oxm.xml";
    private static final String CONTROL_DOC = RESOURCE_DIR + "customer3.xml";
    private static final String JSON_CONTROL_DOC = RESOURCE_DIR + "customer3.json";
    private static final String PACKAGE = "org.eclipse.persistence.testing.jaxb.dynamic.withstatic";

    public StaticWithDynamicTestCases(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 customer = ((DynamicJAXBContext)jaxbContext).newDynamicEntity(PACKAGE + "." + "Customer");
        DynamicEntity phone1 = ((DynamicJAXBContext)jaxbContext).newDynamicEntity(PACKAGE + "." + "PhoneNumber");
        DynamicEntity phone2 = ((DynamicJAXBContext)jaxbContext).newDynamicEntity(PACKAGE + "." + "PhoneNumber");
        DynamicEntity phone3 = ((DynamicJAXBContext)jaxbContext).newDynamicEntity(PACKAGE + "." + "PhoneNumber");
        phone1.set("value", "555-WORK");
        phone1.set("type", "work");
        phone2.set("value", "555-HOME");
        phone2.set("type", "home");
        phone3.set("value", "555-CELL");
        phone3.set("type", "cell");

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

        AddressWithPhone address = new AddressWithPhone();
        address.city = "Any Town";
        address.street = "123 Some Street";
        address.phone = phone3;

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

        return customer;
    }



    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(JAXBContextProperties.OXM_METADATA_SOURCE, 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);
        }

    }
}
