/*
 * Copyright (c) 1998, 2020 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 - 1.0M9 - Initial implementation
package org.eclipse.persistence.testing.sdo.model.type;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import junit.textui.TestRunner;

import org.eclipse.persistence.sdo.helper.SDOXSDHelper;
import org.eclipse.persistence.sdo.helper.SchemaResolver;
import org.eclipse.persistence.testing.sdo.SDOTestCase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.XMLDocument;
import commonj.sdo.impl.HelperProvider;

public class ElementWithBuiltInTypeNameTestCases extends SDOTestCase {
    private static String SCHEMA_PATH = "org/eclipse/persistence/testing/sdo/schemas/elementWithBuiltInTypeName/";

    public ElementWithBuiltInTypeNameTestCases(String name) {
        super(name);
    }

    public static void main(String[] args) throws Exception {
        String[] arguments = { "-c", "org.eclipse.persistence.testing.sdo.model.type.ElementWithBuiltInTypeNameTestCases" };
        TestRunner.main(arguments);
    }

    public void testSingleSchema() {
        HelperContext hc = HelperProvider.getDefaultContext();
        Element[] schemas = new Element[1];
        if ((schemas[0] = getDOM(SCHEMA_PATH + "schema1.xsd")) == null) {
            fail("Couldn't get document element from schema [" + SCHEMA_PATH + "schema1.xsd]");
        }
        try {
            SDOElementResolver resolver = new SDOElementResolver(schemas);
            ((SDOXSDHelper) hc.getXSDHelper()).define(new DOMSource(schemas[0], SCHEMA_PATH + "schema1.xsd"), resolver);
        } catch (Exception x) {
            fail();
        }
    }

    public void testSchemaWithImports() {
        HelperContext hc = HelperProvider.getDefaultContext();

        Element[] schemas = new Element[3];
        if ((schemas[0] = getDOM(SCHEMA_PATH + "schema0.xsd")) == null) {
            fail("Couldn't get document element from schema [" + SCHEMA_PATH + "schema0.xsd]");
        }
        if ((schemas[1] = getDOM(SCHEMA_PATH + "schema1.xsd")) == null) {
            fail("Couldn't get document element from schema [" + SCHEMA_PATH + "schema1.xsd]");
        }
        if ((schemas[2] = getDOM(SCHEMA_PATH + "schema2.xsd")) == null) {
            fail("Couldn't get document element from schema [" + SCHEMA_PATH + "schema2.xsd]");
        }

        SDOElementResolver resolver = new SDOElementResolver(schemas);

        try {
            ((SDOXSDHelper) hc.getXSDHelper()).define(new DOMSource(schemas[0], SCHEMA_PATH + "schema0.xsd"), resolver);
        } catch (Exception x) {
            fail("An exception occurred defining types for schema [" + SCHEMA_PATH + "schema0.xsd]");
        }
        try {
            ((SDOXSDHelper) hc.getXSDHelper()).define(new DOMSource(schemas[1], SCHEMA_PATH + "schema1.xsd"), resolver);
        } catch (Exception x) {
            fail("An exception occurred defining types for schema [" + SCHEMA_PATH + "schema1.xsd]");
        }
        try {
            ((SDOXSDHelper) hc.getXSDHelper()).define(new DOMSource(schemas[2], SCHEMA_PATH + "schema2.xsd"), resolver);
        } catch (Exception x) {
            fail("An exception occurred defining types for schema [" + SCHEMA_PATH + "schema2.xsd]");
        }

        String testMsg1 = " <tns:RetUri xmlns:tns=\"http://tempuri.org/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + "   <tns:inUri>http://test/wsip</tns:inUri>\n" + "  </tns:RetUri>";
        try {
            XMLDocument doc = hc.getXMLHelper().load(testMsg1);
            if (!doc.getRootElementName().equals("RetUri")) {
                fail("Loaded document root element name [" + doc.getRootElementName() + "] is incorrect.  Expected [RetUri]");
            }
            if (!doc.getRootElementURI().equals("http://tempuri.org/")) {
                fail("Loaded document root element uri [" + doc.getRootElementURI() + "] is incorrect.  Expected [http://tempuri.org/]");
            }
        } catch (Exception x) {
            fail("An exception occurred performing a load operation for [" + testMsg1 + "]");
        }
    }

    private Element getDOM(String fileLoc) {
        try {
            FileInputStream is = new FileInputStream(fileLoc);
            DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
            fac.setNamespaceAware(true);
            Document doc = fac.newDocumentBuilder().parse(is);
            return doc.getDocumentElement();
        } catch (Exception e) {
        }
        return null;
    }

    //================================================================================
    static class SDOElementResolver implements SchemaResolver {
        Element[] schemas = null;

        SDOElementResolver(Element[] schemas) {
            this.schemas = schemas;
        }

        public Source resolveSchema(Source sourceXSD, String namespace, String schemaLocation) {
            if (namespace.equals("http://tempuri.org/Imports")) {
                return new DOMSource(schemas[0], SCHEMA_PATH + "schema0.xsd");
            }
            if (namespace.equals("http://www.example.com/")) {
                return new DOMSource(schemas[2], SCHEMA_PATH + "schema1.xsd");
            }
            if (namespace.equals("http://tempuri.org/")) {
                return new DOMSource(schemas[1], SCHEMA_PATH + "schema2.xsd");
            }
            return null;
        }

        public InputSource resolveEntity(String arg0, String arg1) throws SAXException, IOException {
            return null;
        }
    }
}
