/*******************************************************************************
 * Copyright (c) 2011, 2013 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 v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     David McCann - February 09, 2012 - 2.4 - Initial implementation
 ******************************************************************************/
package dbws.testing.optionalarguments;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.StringReader;

import javax.wsdl.WSDLException;

import org.eclipse.persistence.internal.xr.Invocation;
import org.eclipse.persistence.internal.xr.Operation;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.tools.dbws.DBWSBuilder;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;

import dbws.testing.DBWSTestSuite;

/**
 * Tests PL/SQL procedures with optional arguments.
 *
 */
public class OptionalArgumentTestSuite extends DBWSTestSuite {
    static final String CREATE_PHONE_TYPE =
        "CREATE OR REPLACE TYPE DBWS_PHONETYPE AS OBJECT (" +
            "\nHOME VARCHAR2(20)," +
            "\nCELL VARCHAR2(20)" +
        "\n)";
    static final String CREATE_PHONE_TYPE_TABLE =
        "CREATE OR REPLACE TYPE DBWS_PHONETYPE_TABLE AS TABLE OF DBWS_PHONETYPE";
    static final String CREATE_VCARRAY_VARRAY =
        "CREATE OR REPLACE TYPE DBWS_VCARRAY AS VARRAY(4) OF VARCHAR2(20)";
    static final String CREATE_OPTIONALARG_PACKAGE =
        "CREATE OR REPLACE PACKAGE OPTIONALARG AS" +
            "\nPROCEDURE OPTIONAL_ARG1(X IN PLS_INTEGER DEFAULT NULL, Y IN BOOLEAN, Z IN PLS_INTEGER DEFAULT NULL, Q OUT VARCHAR2);" +
            "\nPROCEDURE OPTIONAL_ARG2(X IN DBWS_VCARRAY DEFAULT NULL, Q OUT VARCHAR2);" +
            "\nPROCEDURE OPTIONAL_ARG3(X IN DBWS_PHONETYPE DEFAULT NULL, Q OUT VARCHAR2);" +
            "\nPROCEDURE OPTIONAL_ARG4(X IN DBWS_PHONETYPE_TABLE DEFAULT NULL, Q OUT VARCHAR2);" +
        "\nEND OPTIONALARG;";
    static final String CREATE_OPTIONALARG_BODY =
        "CREATE OR REPLACE PACKAGE BODY OPTIONALARG AS" +
            "\nPROCEDURE OPTIONAL_ARG1(X IN PLS_INTEGER DEFAULT NULL, Y IN BOOLEAN, Z IN PLS_INTEGER DEFAULT NULL, Q OUT VARCHAR2) AS" +
            "\nA PLS_INTEGER := X;" +
            "\nB PLS_INTEGER := Z;" +
            "\nC BOOLEAN;" +
            "\nBEGIN" +
                "\nIF A IS NULL THEN" +
                    "\nA := '-1';" +
                "\nEND IF;" +
                "\nIF B IS NULL THEN" +
	                "\nB := '-1';" +
	            "\nEND IF;" +
                "\nQ := CONCAT(A, ', ');" +
                "\nQ := CONCAT(Q, B);" +
	        "\nEND OPTIONAL_ARG1;" +
            "\nPROCEDURE OPTIONAL_ARG2(X IN DBWS_VCARRAY DEFAULT NULL, Q OUT VARCHAR2) AS" +
            "\nBEGIN" +
	            "\nIF X IS NULL THEN" +
			        "\nQ := 'null';" +
	            "\nELSE" + 
			        "\nQ := 'not null';" +
			    "\nEND IF;" +
	        "\nEND OPTIONAL_ARG2;" +
            "\nPROCEDURE OPTIONAL_ARG3(X IN DBWS_PHONETYPE DEFAULT NULL, Q OUT VARCHAR2) AS" +
            "\nBEGIN" +
	            "\nIF X IS NULL THEN" +
			        "\nQ := 'null';" +
	            "\nELSE" + 
			        "\nQ := CONCAT(X.HOME, ', ');" +
			        "\nQ := CONCAT(Q, X.CELL);" +
			    "\nEND IF;" +
	        "\nEND OPTIONAL_ARG3;" +
            "\nPROCEDURE OPTIONAL_ARG4(X IN DBWS_PHONETYPE_TABLE DEFAULT NULL, Q OUT VARCHAR2) AS" +
	        "\nPHONE1 DBWS_PHONETYPE;" +
	        "\nPHONE2 DBWS_PHONETYPE;" +
            "\nBEGIN" +
	            "\nIF X IS NULL THEN" +
			        "\nQ := 'null';" +
	            "\nELSE" +
			        "\nQ := CONCAT(X(1).HOME, ', ');" +
			        "\nQ := CONCAT(Q, X(1).CELL);" +
			        "\nQ := CONCAT(Q, ' - ');" +
			        "\nQ := CONCAT(Q, X(2).HOME);" +
			        "\nQ := CONCAT(Q, ', ');" +
			        "\nQ := CONCAT(Q, X(2).CELL);" +
			    "\nEND IF;" +
	        "\nEND OPTIONAL_ARG4;" +
        "\nEND OPTIONALARG;";

    static final String DROP_OPTIONALARG_BODY =
        "DROP PACKAGE BODY OPTIONALARG";
    static final String DROP_OPTIONALARG_PACKAGE =
        "DROP PACKAGE OPTIONALARG";
    static final String DROP_DBWS_VCARRAY_TYPE =
        "DROP TYPE DBWS_VCARRAY";
    static final String DROP_DBWS_PHONE_TYPE =
        "DROP TYPE DBWS_PHONETYPE";
    static final String DROP_DBWS_PHONE_TYPE_TABLE =
        "DROP TYPE DBWS_PHONETYPE_TABLE";

    static boolean ddlCreate = false;
    static boolean ddlDrop = false;
    static boolean ddlDebug = false;

    @BeforeClass
    public static void setUp() throws WSDLException {
        if (conn == null) {
            try {
                conn = buildConnection();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        String ddlCreateProp = System.getProperty(DATABASE_DDL_CREATE_KEY, DEFAULT_DATABASE_DDL_CREATE);
        if ("true".equalsIgnoreCase(ddlCreateProp)) {
            ddlCreate = true;
        }
        String ddlDropProp = System.getProperty(DATABASE_DDL_DROP_KEY, DEFAULT_DATABASE_DDL_DROP);
        if ("true".equalsIgnoreCase(ddlDropProp)) {
            ddlDrop = true;
        }
        String ddlDebugProp = System.getProperty(DATABASE_DDL_DEBUG_KEY, DEFAULT_DATABASE_DDL_DEBUG);
        if ("true".equalsIgnoreCase(ddlDebugProp)) {
            ddlDebug = true;
        }
        if (ddlCreate) {
            runDdl(conn, CREATE_VCARRAY_VARRAY, ddlDebug);
            runDdl(conn, CREATE_PHONE_TYPE, ddlDebug);
            runDdl(conn, CREATE_PHONE_TYPE_TABLE, ddlDebug);
            runDdl(conn, CREATE_OPTIONALARG_PACKAGE, ddlDebug);
            runDdl(conn, CREATE_OPTIONALARG_BODY, ddlDebug);
        }
        DBWS_BUILDER_XML_USERNAME =
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
          "<dbws-builder xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
            "<properties>" +
                "<property name=\"projectName\">optionalArgs</property>" +
                "<property name=\"logLevel\">off</property>" +
                "<property name=\"username\">";
        			DBWS_BUILDER_XML_PASSWORD =
                "</property><property name=\"password\">";
                    DBWS_BUILDER_XML_URL =
                "</property><property name=\"url\">";
        			DBWS_BUILDER_XML_DRIVER =
                "</property><property name=\"driver\">";
        			DBWS_BUILDER_XML_PLATFORM =
                "</property><property name=\"platformClassname\">";
        			DBWS_BUILDER_XML_MAIN =
                "</property>" +
            "</properties>" +
            "<plsql-procedure " +
                "name=\"OptionalArgTest1\" " +
                "catalogPattern=\"OPTIONALARG\" " +
                "procedurePattern=\"OPTIONAL_ARG1\" " +
                "isSimpleXMLFormat=\"true\" " +
            "/>" +
            "<plsql-procedure " +
	            "name=\"OptionalArgTest2\" " +
	            "catalogPattern=\"OPTIONALARG\" " +
	            "procedurePattern=\"OPTIONAL_ARG2\" " +
	            "isSimpleXMLFormat=\"true\" " +
	        "/>" +
            "<plsql-procedure " +
	            "name=\"OptionalArgTest3\" " +
	            "catalogPattern=\"OPTIONALARG\" " +
	            "procedurePattern=\"OPTIONAL_ARG3\" " +
	            "isSimpleXMLFormat=\"true\" " +
	        "/>" +
            "<plsql-procedure " +
	            "name=\"OptionalArgTest4\" " +
	            "catalogPattern=\"OPTIONALARG\" " +
	            "procedurePattern=\"OPTIONAL_ARG4\" " +
	            "isSimpleXMLFormat=\"true\" " +
	        "/>" +
          "</dbws-builder>";
          builder = new DBWSBuilder();
          DBWSTestSuite.setUp(".");
    }

    @AfterClass
    public static void tearDown() {
        if (ddlDrop) {
            runDdl(conn, DROP_OPTIONALARG_BODY, ddlDebug);
            runDdl(conn, DROP_OPTIONALARG_PACKAGE, ddlDebug);
            runDdl(conn, DROP_DBWS_VCARRAY_TYPE, ddlDebug);
            runDdl(conn, DROP_DBWS_PHONE_TYPE_TABLE, ddlDebug);
            runDdl(conn, DROP_DBWS_PHONE_TYPE, ddlDebug);
        }
    }

    /**
     * Tests handing in second optional arg.  
     * Expects -1 for 'X'.
     */
    @Test
    public void optionalArgTest1() {
        Invocation invocation = new Invocation("OptionalArgTest1");
        invocation.setParameter("Z", 2);
        invocation.setParameter("Y", true);
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(OPTIONAL_ARG_RESULT1_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    static String OPTIONAL_ARG_RESULT1_XML =
        REGULAR_XML_HEADER +
        "<simple-xml-format>" +
		  "<simple-xml>" +
		    "<Q>-1, 2</Q>" +
		  "</simple-xml>" +
	    "</simple-xml-format>";

    /**
     * Tests handing in first optional arg.
     * Expects -1 for 'Z'.
     */
    @Test
    public void optionalArgTest2() {
        Invocation invocation = new Invocation("OptionalArgTest1");
        invocation.setParameter("X", 2);
        invocation.setParameter("Y", true);
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(OPTIONAL_ARG_RESULT2_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    static String OPTIONAL_ARG_RESULT2_XML =
        REGULAR_XML_HEADER +
        "<simple-xml-format>" +
		  "<simple-xml>" +
		    "<Q>2, -1</Q>" +
		  "</simple-xml>" +
	    "</simple-xml-format>";

    /**
     * Tests handing in no optional args.
     * Expects -1 for 'X' & 'Z'.
     */
    @Test
    public void optionalArgTest3() {
        Invocation invocation = new Invocation("OptionalArgTest1");
        invocation.setParameter("Y", true);
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(OPTIONAL_ARG_RESULT3_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    static String OPTIONAL_ARG_RESULT3_XML =
        REGULAR_XML_HEADER +
        "<simple-xml-format>" +
		  "<simple-xml>" +
		    "<Q>-1, -1</Q>" +
		  "</simple-xml>" +
	    "</simple-xml-format>";

    @Test
    public void optionalArgTest4() {
        Invocation invocation = new Invocation("OptionalArgTest1");
        invocation.setParameter("X", 66);
        invocation.setParameter("Z", 99);
        invocation.setParameter("Y", true);
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(OPTIONAL_ARG_RESULT5_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    static String OPTIONAL_ARG_RESULT5_XML =
        REGULAR_XML_HEADER +
        "<simple-xml-format>" +
		  "<simple-xml>" +
		    "<Q>66, 99</Q>" +
		  "</simple-xml>" +
	    "</simple-xml-format>";

    /**
     * Tests VArray default.  
     * Expects 'null'.
     */
    @Test
    public void optionalVArrayArgTest1() {
        Invocation invocation = new Invocation("OptionalArgTest2");
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(NULL_RESULT_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    static String NULL_RESULT_XML =
        REGULAR_XML_HEADER +
        "<simple-xml-format>" +
		  "<simple-xml>" +
		    "<Q>null</Q>" +
		  "</simple-xml>" +
	    "</simple-xml-format>";
    
    /**
     * Tests VArray default.  
     * Expects 'not-null'.
     */
    @Test
    public void optionalVArrayArgTest2() {
        XMLUnmarshaller unmarshaller = xrService.getXMLContext().createUnmarshaller();
        Object input = unmarshaller.unmarshal(new StringReader(INPUT_XML));
        Invocation invocation = new Invocation("OptionalArgTest2");
        invocation.setParameter("X", input);
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(NOT_NULL_RESULT_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    static String INPUT_XML =
        REGULAR_XML_HEADER +
        "<dbws_vcarrayType xmlns=\"urn:optionalArgs\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
            "<item>one</item>" +
            "<item>two</item>" +
        "</dbws_vcarrayType>";
    static String NOT_NULL_RESULT_XML =
        REGULAR_XML_HEADER +
        "<simple-xml-format>" +
		  "<simple-xml>" +
		    "<Q>not null</Q>" +
		  "</simple-xml>" +
	    "</simple-xml-format>";

    /**
     * Tests Object default.  
     * Expects 'null'.
     */
    @Test
    public void optionalObjectArgTest1() {
        Invocation invocation = new Invocation("OptionalArgTest3");
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(NULL_RESULT_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    
    /**
     * Tests Object default.  
     * Expects '(613)123-1234, (902)678-6789'.
     */
    @Test
    public void optionalObjectArgTest2() {
        XMLUnmarshaller unmarshaller = xrService.getXMLContext().createUnmarshaller();
        Object input = unmarshaller.unmarshal(new StringReader(PHONE_INPUT_XML));
        Invocation invocation = new Invocation("OptionalArgTest3");
        invocation.setParameter("X", input);
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(PHONE_RESULT_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    static String PHONE_INPUT_XML =
        REGULAR_XML_HEADER +
        "<dbws_phonetypeType xmlns=\"urn:optionalArgs\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
            "<home>(613)123-1234</home>" +
            "<cell>(902)678-6789</cell>" +
        "</dbws_phonetypeType>";
    static String PHONE_RESULT_XML =
        REGULAR_XML_HEADER +
        "<simple-xml-format>" +
		  "<simple-xml>" +
		    "<Q>(613)123-1234, (902)678-6789</Q>" +
		  "</simple-xml>" +
	    "</simple-xml-format>";

    /**
     * Tests ObjectTable default.  
     * Expects 'null'.
     */
    @Test
    public void optionalObjectTableArgTest1() {
        Invocation invocation = new Invocation("OptionalArgTest4");
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(NULL_RESULT_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }

    /**
     * Tests ObjectTable default.  
     * Expects ''.
     */
    @Test
    public void optionalObjectTableArgTest2() {
        XMLUnmarshaller unmarshaller = xrService.getXMLContext().createUnmarshaller();
        Object input = unmarshaller.unmarshal(new StringReader(PHONE_TABLE_INPUT_XML));
        Invocation invocation = new Invocation("OptionalArgTest4");
        invocation.setParameter("X", input);
        Operation op = xrService.getOperation(invocation.getName());
        Object result = op.invoke(xrService, invocation);
        assertNotNull("result is null", result);
        Document doc = xmlPlatform.createDocument();
        XMLMarshaller marshaller = xrService.getXMLContext().createMarshaller();
        marshaller.marshal(result, doc);
        Document controlDoc = xmlParser.parse(new StringReader(PHONE_TABLE_RESULT_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }

    static String PHONE_TABLE_INPUT_XML =
        REGULAR_XML_HEADER +
        "<dbws_phonetype_tableType xmlns=\"urn:optionalArgs\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
        	"<item>" +
	            "<home>(613)123-1234</home>" +
	            "<cell>(902)678-6789</cell>" +
        	"</item>" +
        	"<item>" +
	            "<home>(613)234-4567</home>" +
	            "<cell>(902)987-9876</cell>" +
        	"</item>" +
        "</dbws_phonetype_tableType>";
    static String PHONE_TABLE_RESULT_XML =
        REGULAR_XML_HEADER +
        "<simple-xml-format>" +
		  "<simple-xml>" +
		    "<Q>(613)123-1234, (902)678-6789 - (613)234-4567, (902)987-9876</Q>" +
		  "</simple-xml>" +
	    "</simple-xml-format>";
}
