/*
 * 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:
//     Oracle - initial API and implementation
package org.eclipse.persistence.testing.jaxb.externalizedmetadata.mappings.anyattribute;

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

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

import org.eclipse.persistence.jaxb.*;
import org.eclipse.persistence.testing.jaxb.JAXBWithJSONTestCases;

/**
 * Tests XmlAnyAttributeMapping via eclipselink-oxm.xml
 *
 */
public class AnyAttributeSubTypeMappingTestCases extends JAXBWithJSONTestCases {

    private static final String XML_RESOURCE = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/mappings/anyattribute/subtype-map.xml";
    private static final String JSON_RESOURCE = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/mappings/anyattribute/subtype-map.json";
    private static final String JSON_RESOURCE2 = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/mappings/anyattribute/subtype-map2.json";

    private static final String NAME_1 = "Joe";
    private static final String NAME_2 = "Bob";
    private static final String CHILD1_NAME = "child-1";
    private static final String CHILD2_NAME = "child-2";
    private static final String OTHER_NS = "http://www.example.com/other";

    /**
     * This is the preferred (and only) constructor.
     *
     */
    public AnyAttributeSubTypeMappingTestCases(String name) throws Exception {
        super(name);
        setControlDocument(XML_RESOURCE);
        setControlJSON(JSON_RESOURCE);
        setClasses(new Class[]{XmlAnyAttributeSubTypeMapModel.class});

        Map<String, String> namespaces = new HashMap<String, String>();
        namespaces.put("http://www.example.com/other", "ns0");
        jaxbUnmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, namespaces);
    }

    @Override
    public JAXBMarshaller getJSONMarshaller() throws Exception{
        JAXBMarshaller jsonMarshaller = (JAXBMarshaller) jaxbContext.createMarshaller();
        jsonMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        Map<String, String> namespaces = new HashMap<String, String>();
        namespaces.put("http://www.example.com/other", "ns0");

        jsonMarshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaces);
        return jsonMarshaller;

      }

    /**
     * Create the control XmlAnyAttributeSubTypeMapModel.
     */
    @Override
    public Object getControlObject() {
        XmlAnyAttributeSubTypeMapModel anyAttributeSubTypeMapModel = new XmlAnyAttributeSubTypeMapModel();
        LinkedHashMap children = new LinkedHashMap();
        QName qname = new QName(OTHER_NS, CHILD1_NAME);
        children.put(qname, NAME_1);
        qname = new QName(OTHER_NS, CHILD2_NAME);
        children.put(qname, NAME_2);
        anyAttributeSubTypeMapModel.children = children;
        return anyAttributeSubTypeMapModel;
    }

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

        HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
        metadataSourceMap.put("org.eclipse.persistence.testing.jaxb.externalizedmetadata.mappings.anyattribute", new StreamSource(inputStream));
        Map<String, Map<String, Source>> properties = new HashMap<String, Map<String, Source>>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);

        return properties;
    }

    public void testSchemaGen() throws Exception{
        List controlSchemas = new ArrayList();
        InputStream is = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/mappings/anyattribute/subtype-map.xsd");
        controlSchemas.add(is);

        super.testSchemaGen(controlSchemas);
    }

    protected void compareStrings(String test, String testString) {
          log(test);
          if(shouldRemoveEmptyTextNodesFromControlDoc()){
              log("Expected (With All Whitespace Removed):");
          }else{
                log("Expected");
          }

          String expectedString = loadFileToString(JSON_RESOURCE);
          if(shouldRemoveEmptyTextNodesFromControlDoc()){
              expectedString = expectedString.replaceAll("[ \b\t\n\r ]", "");
          }
          log(expectedString);
          if(shouldRemoveEmptyTextNodesFromControlDoc()){
              log("\nActual (With All Whitespace Removed):");
          }else{
              log("\nActual");
          }

          if(shouldRemoveEmptyTextNodesFromControlDoc()){
              testString = testString.replaceAll("[ \b\t\n\r]", "");
          }
          log(testString);

          if(expectedString.equals(testString)){
              return;
          }
          //try second document with values in a different order
          expectedString = loadFileToString(JSON_RESOURCE2);
          if(shouldRemoveEmptyTextNodesFromControlDoc()){
               expectedString = expectedString.replaceAll("[ \b\t\n\r ]", "");
          }
          log(expectedString);
          if(shouldRemoveEmptyTextNodesFromControlDoc()){
              log("\nActual (With All Whitespace Removed):");
          }else{
              log("\nActual");
          }
          assertEquals(expectedString, testString);
    }
}

