/*
 * 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 DynamicWithStaticAddressNoPropsTestCases 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_PROPS = RESOURCE_DIR + "address-no-props-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 DynamicWithStaticAddressNoPropsTestCases(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_PROPS);
      if (iStream == null) {
          fail("Couldn't load metadata file [" + NO_PROPS + "]");
      }

      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(getJSONReadControlObject().toString());
      log("Actual:");
      log(testObject.toString());

      compareDynamicEntities(testObject, getJSONReadControlObject());
  }

  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);
      }

  }
}
