/*
 * 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:
//     David McCann - September 08, 2011 - 2.4 - Initial implementation
package dbws.testing.rowtype;

//javase imports
import java.io.StringReader;
import java.sql.SQLException;
import java.sql.Statement;
import org.w3c.dom.Document;

//java eXtension imports
import javax.wsdl.WSDLException;

//JUnit4 imports
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

//EclipseLink imports
import org.eclipse.persistence.internal.xr.Invocation;
import org.eclipse.persistence.internal.xr.Operation;
import org.eclipse.persistence.oxm.XMLMarshaller;

//test imports
import dbws.testing.DBWSTestSuite;

/**
 * Tests %ROWTYPE support. If, in a PL/SQL package, you want a record
 * with fields (names &amp; types, but not constraints) that mirror a
 * JDBC table, without defining the record in the package, %ROWTYPE
 * can be used, i.e. "PARAM1 OUT MYTABLE%ROWTYPE".
 *
 */
public class RowTypeTestSuite extends DBWSTestSuite {

    static final String WSDL_REF = "ref=\"ns1:rtype_table_rowtypeType\"";
    static final String XSD =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
        "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"urn:rowtype\" xmlns=\"urn:rowtype\" elementFormDefault=\"qualified\">" +
           "<xsd:complexType name=\"rtype_table_rowtypeType\">" +
              "<xsd:sequence>" +
                 "<xsd:element name=\"id\" type=\"xsd:decimal\" minOccurs=\"0\" nillable=\"true\"/>" +
                 "<xsd:element name=\"name\" type=\"xsd:string\" minOccurs=\"0\" nillable=\"true\"/>" +
                 "<xsd:element name=\"since\" type=\"xsd:date\" minOccurs=\"0\" nillable=\"true\"/>" +
              "</xsd:sequence>" +
           "</xsd:complexType>" +
           "<xsd:element name=\"rtype_table_rowtypeType\" type=\"rtype_table_rowtypeType\"/>" +
        "</xsd:schema>";
    static final String SERVICE =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
        "<dbws xmlns:ns1=\"urn:rowtype\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
           "<name>rowtype</name>" +
           "<sessions-file>eclipselink-dbws-sessions.xml</sessions-file>" +
           "<query>" +
              "<name>rowtypeTest</name>" +
              "<parameter>" +
                 "<name>PARAM1</name>" +
                 "<type>xsd:int</type>" +
              "</parameter>" +
              "<result>" +
                 "<type>ns1:rtype_table_rowtypeType</type>" +
              "</result>" +
              "<named-query>" +
                 "<name>rowtypeTest</name>" +
              "</named-query>" +
           "</query>" +
           "<query>" +
              "<name>rowtypeTest2</name>" +
              "<parameter>" +
                 "<name>PARAM1</name>" +
                 "<type>xsd:int</type>" +
              "</parameter>" +
              "<result>" +
                 "<type>ns1:rtype_table_rowtypeType</type>" +
              "</result>" +
              "<named-query>" +
                 "<name>rowtypeTest2</name>" +
              "</named-query>" +
            "</query>" +
        "</dbws>";


    static final String ROWTYPE_TEST_TABLE = "RTYPE_TABLE";
    static final String CREATE_ROWTYPE_TEST_TABLE = "CREATE TABLE " + ROWTYPE_TEST_TABLE + " (" +
        "\nID NUMBER NOT NULL," +
        "\nNAME VARCHAR(25)," +
        "\nSINCE DATE," +
        "\nPRIMARY KEY (ID)" +
    "\n)";
    static final String[] POPULATE_ROWTYPE_TEST_TABLE = new String[] {
        "INSERT INTO " + ROWTYPE_TEST_TABLE + " (ID, NAME, SINCE) VALUES (1, 'Conky', " +
            "TO_DATE('2001-12-25 00:00:00','YYYY-MM-DD HH24:MI:SS'))",
        "INSERT INTO " + ROWTYPE_TEST_TABLE + " (ID, NAME, SINCE) VALUES (2, 'Ricky', " +
            "TO_DATE('2002-02-12 00:00:00','YYYY-MM-DD HH24:MI:SS'))",
        "INSERT INTO " + ROWTYPE_TEST_TABLE + " (ID, NAME, SINCE) VALUES (3, 'Bubbles'," +
            "TO_DATE('2001-10-30 00:00:00','YYYY-MM-DD HH24:MI:SS'))",
        "INSERT INTO " + ROWTYPE_TEST_TABLE + " (ID, NAME, SINCE) VALUES (4, 'Julian', " +
            "TO_DATE('2010-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS'))"
    };
    static final String ROWTYPE_TEST_PACKAGE = "RTYPE_PKG";
    static final String CREATE_ROWTYPE_TEST_PACKAGE =
        "CREATE OR REPLACE PACKAGE " + ROWTYPE_TEST_PACKAGE + " AS" +
            "\nPROCEDURE testProc(PARAM1 IN INTEGER, PARAM2 OUT " + ROWTYPE_TEST_TABLE + "%ROWTYPE);" +
            "\nFUNCTION test(PARAM1 IN INTEGER) RETURN " + ROWTYPE_TEST_TABLE + "%ROWTYPE;" +
        "\nEND " + ROWTYPE_TEST_PACKAGE + ";";

    static final String CREATE_ROWTYPE_TEST_PACKAGE_BODY =
        "CREATE OR REPLACE PACKAGE BODY " + ROWTYPE_TEST_PACKAGE + " AS" +
            "\nPROCEDURE testProc(PARAM1 IN INTEGER, PARAM2 OUT " + ROWTYPE_TEST_TABLE + "%ROWTYPE) AS" +
            "\nBEGIN" +
              "\nPARAM2 := test(PARAM1);" +
            "\nEND testProc;" +
            "\nFUNCTION test(PARAM1 IN INTEGER) RETURN " + ROWTYPE_TEST_TABLE + "%ROWTYPE AS" +
                "\nL_DATA1 " + ROWTYPE_TEST_TABLE + "%ROWTYPE;" +
                "\nCURSOR C_EMP(PARAMTEMP IN INTEGER) IS SELECT * FROM " + ROWTYPE_TEST_TABLE +
                    " WHERE " + ROWTYPE_TEST_TABLE + ".ID=PARAMTEMP;" +
            "\nBEGIN" +
                "\nOPEN C_EMP(PARAM1);" +
                "\nLOOP" +
                "\nFETCH C_EMP INTO L_DATA1;" +
                "\nEXIT WHEN C_EMP%NOTFOUND;" +
                "\nEND LOOP;" +
                "\nRETURN L_DATA1;" +
            "\nEND test;" +
        "\nEND " + ROWTYPE_TEST_PACKAGE + ";";

    static final String DROP_ROWTYPE_TEST_TABLE = "DROP TABLE " + ROWTYPE_TEST_TABLE;
    static final String DROP_ROWTYPE_SHADOWTYPE = "DROP TYPE " + ROWTYPE_TEST_TABLE + "_ROWTYPE";
    static final String DROP_ROWTYPE_TEST_PACKAGE = "DROP PACKAGE " + ROWTYPE_TEST_PACKAGE;

    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_ROWTYPE_TEST_TABLE, ddlDebug);
            try {
                Statement stmt = conn.createStatement();
                for (int i = 0; i < POPULATE_ROWTYPE_TEST_TABLE.length; i++) {
                    stmt.addBatch(POPULATE_ROWTYPE_TEST_TABLE[i]);
                }
                stmt.executeBatch();
            }
            catch (SQLException e) {
                //e.printStackTrace();
            }
            runDdl(conn, CREATE_ROWTYPE_TEST_PACKAGE, ddlDebug);
            runDdl(conn, CREATE_ROWTYPE_TEST_PACKAGE_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\">rowtype</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=\"rowtypeTest2\" " +
                  "catalogPattern=\"" + ROWTYPE_TEST_PACKAGE + "\" " +
                  "procedurePattern=\"testProc\" " +
               "/>" +
              "<plsql-procedure " +
                  "name=\"rowtypeTest\" " +
                  "catalogPattern=\"" + ROWTYPE_TEST_PACKAGE + "\" " +
                  "procedurePattern=\"test\" " +
               "/>" +
            "</dbws-builder>";
          builder = null;
          DBWSTestSuite.setUp(".");

          // execute shadow type ddl to generate JDBC equivalents of PL/SQL types
          for (String ddl : builder.getTypeDDL()) {
              runDdl(conn, ddl, ddlDebug);
          }
    }

    @AfterClass
    public static void tearDown() {
        String ddlDrop = System.getProperty(DATABASE_DDL_DROP_KEY, DEFAULT_DATABASE_DDL_DROP);
        if ("true".equalsIgnoreCase(ddlDrop)) {
            runDdl(conn, DROP_ROWTYPE_TEST_PACKAGE, ddlDebug);
            runDdl(conn, DROP_ROWTYPE_TEST_TABLE, ddlDebug);
        }
        // drop shadow type ddl
        for (String ddl : builder.getTypeDropDDL()) {
                runDdl(conn, ddl, ddlDebug);
        }
    }

    @Test
    public void rowTypeTest() {
        Invocation invocation = new Invocation("rowtypeTest");
        Operation op = xrService.getOperation(invocation.getName());
        invocation.setParameter("PARAM1", 1);
        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(RECORD_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    @Test
    public void rowTypeTest2() {
        Invocation invocation = new Invocation("rowtypeTest2");
        Operation op = xrService.getOperation(invocation.getName());
        invocation.setParameter("PARAM1", 1);
        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(RECORD_XML));
        assertTrue("Expected:\n" + documentToString(controlDoc) + "\nActual:\n" + documentToString(doc), comparer.isNodeEqual(controlDoc, doc));
    }
    public static final String RECORD_XML =
        STANDALONE_XML_HEADER +
        "<rtype_table_rowtypeType xmlns=\"urn:rowtype\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
            "<id>1</id>" +
            "<name>Conky</name>" +
            "<since>2001-12-25</since>" +
        "</rtype_table_rowtypeType>";

    /**
     * Test element/complex type names do not contain '%'
     */
    @Test
    public void compareXSD() {
        assertNotNull("Schema stream is null", DBWS_SCHEMA_STREAM);
        Document controlDoc = xmlParser.parse(new StringReader(XSD));
        removeEmptyTextNodes(controlDoc);
        Document testDoc = xmlParser.parse(new StringReader(DBWS_SCHEMA_STREAM.toString()));
        removeEmptyTextNodes(testDoc);
        assertTrue("Schema comparison failed.  Expected:\n" + documentToString(controlDoc) + "\nActual\n" + documentToString(testDoc), comparer.isNodeEqual(controlDoc, testDoc));
    }

    /**
     * Test type names do not contain '%'
     */
    @Test
    public void compareSessions() {
        assertNotNull("Service stream is null", DBWS_SERVICE_STREAM);
        Document controlDoc = xmlParser.parse(new StringReader(SERVICE));
        removeEmptyTextNodes(controlDoc);
        Document testDoc = xmlParser.parse(new StringReader(DBWS_SERVICE_STREAM.toString()));
        removeEmptyTextNodes(testDoc);
        assertTrue("Service file comparison failed.  Expected:\n" + documentToString(controlDoc) + "\nActual\n" + documentToString(testDoc), comparer.isNodeEqual(controlDoc, testDoc));
    }

    /**
     * Test element ref name does not contain '%'
     */
    @Test
    public void compareWSDLElementRef() {
        assertNotNull("WSDL stream is null", DBWS_WSDL_STREAM);
        assertTrue("Expected to find:\n" + WSDL_REF + "\nbut did not.  WSDL:\n" + DBWS_WSDL_STREAM.toString(), DBWS_WSDL_STREAM.toString().contains(WSDL_REF));
    }
}
