/*
 * 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:
//     Mike Norman - from Proof-of-concept, become production code
package dbws.testing.shadowddlgeneration.oldjpub;

//javase imports
import java.lang.reflect.Modifier;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;

//EclipseLink imports
import dbws.testing.shadowddlgeneration.oldjpub.MethodFilter;
import dbws.testing.shadowddlgeneration.oldjpub.PublisherException;
import dbws.testing.shadowddlgeneration.oldjpub.Util;
import dbws.testing.shadowddlgeneration.oldjpub.MethodInfo;
import dbws.testing.shadowddlgeneration.oldjpub.ParamInfo;
import dbws.testing.shadowddlgeneration.oldjpub.ResultInfo;
import dbws.testing.shadowddlgeneration.oldjpub.SingleColumnViewRow;
import dbws.testing.shadowddlgeneration.oldjpub.ViewRow;

public abstract class SqlTypeWithMethods extends SqlTypeWithFields {

    public SqlTypeWithMethods(SqlName sqlName, int typecode, boolean generateMe,
        SqlType parentType, MethodFilter signatureFilter, SqlReflector reflector)
        throws SQLException {
        super(sqlName, typecode, generateMe, parentType, reflector);
        m_methodFilter = signatureFilter;
    }

    /**
     * Returns an array of Method objects reflecting all the methods declared by this
     * SqlTypeWithMethods object. Returns an array of length 0 if the SqlTypeWithMethods declares no
     * methods
     */
    @Override
    public List<ProcedureMethod> getDeclaredMethods() throws SQLException, PublisherException {
        if (m_methods == null) {
            m_methods = reflectMethods(getSqlName());
        }
        return m_methods;
    }

    @Override
    public boolean hasMethods() throws SQLException, PublisherException {
        List<ProcedureMethod> m = getDeclaredMethods();
        return m != null && m.size() > 0;
    }

    private List<ProcedureMethod> reflectMethods(SqlName sqlName) throws SQLException, PublisherException {
        String schema = sqlName.getSchemaName();
        String type = sqlName.getTypeName();
        ArrayList<ProcedureMethod> methodl = new ArrayList<ProcedureMethod>();

        /* get method information */
        MethodInfo[] minfo = getMethodInfo(schema, type);
        for (int minfoi = 0; minfoi < minfo.length; minfoi++) {
            String methodName = minfo[minfoi].methodName;
            String methodType = minfo[minfoi].methodType;
            String methodNo = minfo[minfoi].methodNo;
            int results = minfo[minfoi].results;
            int parameters = minfo[minfoi].parameters;

            // Pre-approve the method, to avoid unwanted methods during Toplevel publishing.
            boolean preApproved = true;
            if (m_methodFilter != null) {
                preApproved = m_methodFilter.acceptMethod(new ProcedureMethod(methodName, null, -1, null,
                    null, null, null, null, 0), true);
            }
            if (!preApproved) {
                continue;
            }

            int modifiers;
            modifiers = Modifier.PUBLIC;
            if (methodType.equals("MAP")) {
                modifiers = modifiers ^ PublisherModifier.MAP;
            }
            else if (methodType.equals("ORDER")) {
                modifiers = modifiers ^ PublisherModifier.ORDER;
            }

            TypeClass returnType = null;
            ResultInfo resultInfo = null;

            /* get return type information */
            if (results > 0) {
                resultInfo = getResultInfo(schema, type, methodName, methodNo);
                if (resultInfo != null) {
                    try {
                        String resultTypeOwner = resultInfo.resultTypeOwner;
                        String resultTypeName = resultInfo.resultTypeName;
                        String resultTypeSubname = resultInfo.resultTypeSubname;
                        String resultTypeMod = resultInfo.resultTypeMod;
                        boolean ncharFormOfUse = resultInfo.ncharFormOfUse;
                        String resultMethodName = resultInfo.methodName;
                        String resultMethodNo = resultInfo.methodNo;
                        int sequence = resultInfo.sequence;
                        returnType = m_reflector.addPlsqlDBType(resultTypeOwner, resultTypeName,
                            resultTypeSubname, resultTypeMod, ncharFormOfUse, type,
                            resultMethodName, resultMethodNo, sequence, this);
                    }
                    catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }

            /* get parameter information */
            int paramCount = parameters;
            List<TypeClass> paramTypes_v = new ArrayList<TypeClass>();
            List<String> paramNames_v = new ArrayList<String>();
            List<Integer> paramModes_v = new ArrayList<Integer>();
            List<Boolean> paramNCharFormOfUse_v = new ArrayList<Boolean>();
            int firstNoDefault = -1;
            boolean[] paramDefaults = new boolean[paramCount];
            if (paramCount > 0) {
                ParamInfo[] pinfo = null;
                pinfo = getParamInfo(schema, type, methodName, methodNo);
                String[] paramTypeOwner = new String[paramCount];
                String[] paramName = new String[paramCount];
                String[] paramTypeName = new String[paramCount];
                String[] paramTypeSubname = new String[paramCount];
                String[] paramTypeMod = new String[paramCount];
                String[] paramMode = new String[paramCount];
                boolean[] mcharFormOfUse = new boolean[paramCount];
                String[] paramMethodName = new String[paramCount];
                String[] paramMethodNo = new String[paramCount];
                int[] sequence = new int[paramCount];
                int[] objectId = new int[paramCount];
                for (int i = pinfo.length - 1; i >= 0; i--) {
                    paramTypeOwner[i] = pinfo[i].paramTypeOwner;
                    paramName[i] = pinfo[i].paramName;
                    paramTypeName[i] = pinfo[i].paramTypeName;
                    paramTypeSubname[i] = pinfo[i].paramTypeSubname;
                    paramTypeMod[i] = pinfo[i].paramTypeMod;
                    paramMode[i] = pinfo[i].paramMode;
                    mcharFormOfUse[i] = pinfo[i].ncharFormOfUse;
                    paramMethodName[i] = pinfo[i].methodName;
                    paramMethodNo[i] = pinfo[i].methodNo;
                    sequence[i] = pinfo[i].sequence;
                    objectId[i] = pinfo[i].objectId;
                }
                paramDefaults = new boolean[pinfo.length];
                for (int i = pinfo.length - 1; i >= 0; i--) {
                    paramDefaults[i] = hasDefault(objectId[i], paramMethodName[i], sequence[i],
                        paramMethodNo[i]);
                }
                for (int i = pinfo.length - 1; i >= 0; i--) {
                    if (!paramDefaults[i]) {
                        firstNoDefault = i;
                        break;
                    }
                }
                for (int i = 0; i < paramCount && paramMethodName[i] != null; i++) {
                    try {
                        paramNames_v.add(paramName[i]);
                        String mode = paramMode[i];
                        paramModes_v.add((mode == null) ? ProcedureMethod.INOUT : (mode
                                .equals("IN") ? ProcedureMethod.IN : (mode.equals("OUT") ? ProcedureMethod.OUT
                                : ProcedureMethod.INOUT)));
                        paramTypes_v.add(m_reflector.addPlsqlDBType(paramTypeOwner[i],
                            paramTypeName[i], paramTypeSubname[i], paramTypeMod[i],
                            mcharFormOfUse[i], type, paramMethodName[i], paramMethodNo[i],
                            sequence[i], this));
                        paramNCharFormOfUse_v.add(mcharFormOfUse[i]);
                    }
                    catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }

            int len = paramTypes_v.size();
            if (len != paramCount) {
                System.err.println("WARNING: incorrect parameter number for method " + methodName
                    + ". Expect " + paramCount + " with actual " + len);

            }

            TypeClass[] paramTypes = new TypeClass[len];
            String[] paramNames = new String[len];
            int[] paramModes = new int[len];
            boolean[] paramNCharFormOfUse = new boolean[len];
            for (int i = 0; i < len; i++) {
                paramTypes[i] = (paramTypes_v.get(i));
                paramNames[i] = paramNames_v.get(i);
                paramModes[i] = paramModes_v.get(i);
                paramNCharFormOfUse[i] = paramNCharFormOfUse_v.get(i);
            }

            paramTypes = generateDefaultArgsHolderParamTypes(paramTypes, paramDefaults,
                paramNCharFormOfUse);
            ProcedureMethod method = null;
            for (int paramLen = firstNoDefault + 1; paramLen <= paramCount; paramLen++) {
                if (this instanceof SqlPackageType && returnType != null && resultInfo != null
                    && returnType.equals(SqlReflector.REF_CURSOR_TYPE)) {
                    method = new PlsqlCursorMethod(type, methodName, methodNo, modifiers,
                        resultInfo.sequence, paramTypes, paramNames, paramModes, paramDefaults,
                        paramLen, false, m_reflector);
                }
                else if (this instanceof SqlPackageType) {
                    method = new PlsqlMethod(methodName, methodNo, modifiers, returnType,
                        paramTypes, paramNames, paramModes, paramDefaults, paramLen);
                }
                else {
                    method = new ProcedureMethod(methodName, methodNo, modifiers, returnType, paramTypes,
                        paramNames, paramModes, paramDefaults, paramLen);
                }

                if (acceptMethod(method, false)) {
                    methodl.add(method);
                    if (returnType != null && resultInfo != null
                        && returnType.equals(SqlReflector.REF_CURSOR_TYPE)) {
                        method = new PlsqlCursorMethod(type, methodName, methodNo, modifiers,
                            resultInfo.sequence, paramTypes, paramNames, paramModes, paramDefaults,
                            paramLen, true, /* returnBeans */
                            m_reflector);
                        if (((PlsqlCursorMethod)method).getReturnColCount() != 0) {
                            methodl.add(method);
                        }
                    }
                }
            }
        }
        Collections.sort(methodl);
        return methodl;
    }

    protected abstract MethodInfo[] getMethodInfo(String schema, String name) throws SQLException;

    protected boolean acceptMethod(ProcedureMethod method, boolean preApprove) {
        boolean accept = true;
        if (m_methodFilter != null) {
            accept = m_methodFilter.acceptMethod(method, preApprove);
        }
        return accept;
    }

    protected abstract ResultInfo getResultInfo(String schema, String name, String method,
        String methodNo) throws SQLException;

    protected abstract ParamInfo[] getParamInfo(String schema, String name, String method,
        String methodNo) throws SQLException;

    @SuppressWarnings("unused")
    protected boolean hasDefault(int object_id, String methodName, int sequence, String overload)
        throws SQLException {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        final int objectIdIdx = 1;
        final int objectNameIdx = 2;
        final int seqIdx = 3;
        int hasDefaultInt = 0;

        /*
         * Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null;
         *
         * conn = m_reflector.getConnection();
         *
         * if (overload == null || overload.equals("")) { stmt =conn.prepareStatement(
         * "SELECT DEFAULTED FROM ALL_ARGUMENTS WHERE OBJECT_ID=:1 AND OBJECT_NAME=:2 AND SEQUENCE=:3 AND OVERLOAD IS NULL"
         * ); } else { stmt =conn.prepareStatement(
         * "SELECT DEFAULTED FROM ALL_ARGUMENTS WHERE OBJECT_ID=:1 AND OBJECT_NAME=:2 AND SEQUENCE=:3 AND OVERLOAD='"
         * + overload + "'"); } stmt.setInt(objectIdIdx, object_id); stmt.setString(objectNameIdx,
         * methodName); stmt.setInt(seqIdx, sequence); try { rs = stmt.executeQuery(); if
         * (rs.next()) { String defaulted = rs.getString(1); hasDefaultInt =
         * "Y".equalsIgnoreCase(defaulted) ? 1 : 0; }
         */
        try {
            Iterator<ViewRow> rowIter;
            if (overload == null || overload.equals("")) {
                rowIter = m_viewCache.getRows(Util.ALL_ARGUMENTS, new String[]{"DEFAULTED"},
                    new String[]{"OBJECT_ID", "OBJECT_NAME", "SEQUENCE", "OVERLOAD"}, new Object[]{
                                object_id, methodName, sequence, null},
                    new String[0]);
            }
            else {
                rowIter = m_viewCache.getRows(Util.ALL_ARGUMENTS, new String[]{"DEFAULTED"},
                    new String[]{"OBJECT_ID", "OBJECT_NAME", "SEQUENCE", "OVERLOAD"}, new Object[]{
                                object_id, methodName, sequence, overload},
                    new String[0]);
            }
            if (rowIter.hasNext()) {
                SingleColumnViewRow row = (SingleColumnViewRow)rowIter.next();
                String defaulted = row.getValue();
                hasDefaultInt = "Y".equalsIgnoreCase(defaulted) ? 1 : 0;
            }
            else {
                throw new SQLException(
                    "Pre-10.2 database do not support DEFAULTED in ALL_ARGUMENTS");
            }
        }
        catch (Exception se) { // SQLException: ORA-00904: "DEFAULTED": invalid identifier
            // se.printStackTrace();
            // conn = m_reflector.getConnection();
            try {
                // DEFAULTED ONLY EXISTS in Database 10.2
                final int oidIdx = 1;
                final int methodNameIdx = 2;
                final int sequenceIdx = 3;
                final int overloadIdx = 4;

                /*
                 * if (stmt != null) { stmt.close(); } if (rs != null) { rs.close(); }
                 *
                 * stmt =
                 * conn.prepareStatement("SELECT SYS.SQLJUTL.HAS_DEFAULT(:1, :2, :3, :4) FROM DUAL"
                 * ); stmt.setInt(oidIdx, object_id); stmt.setString(methodNameIdx, methodName);
                 * stmt.setInt(sequenceIdx, sequence); if (overload == null || overload.equals(""))
                 * { stmt.setInt(overloadIdx, 0); } else { stmt.setInt(overloadIdx,
                 * Integer.parseInt(overload)); } rs = stmt.executeQuery(); boolean hasNext =
                 * rs.next(); if (hasNext) { hasDefaultInt = rs.getInt(1); }
                 */

                String sqljutl = "SYS.SQLJUTL.HAS_DEFAULT(" + object_id + ", " + "'"
                    + methodName.toUpperCase() + "', " + sequence + ","
                    + ((overload == null || overload.equals("")) ? "0" : overload) + ")";
                Iterator<ViewRow> rowIter = m_viewCache.getRows(Util.DUAL, new String[]{sqljutl},
                    new String[0], new Object[0], new String[0]);

                if (rowIter.hasNext()) {
                    SingleColumnViewRow row = (SingleColumnViewRow)rowIter.next();
                    if (row.getValue() != null) {
                        hasDefaultInt = Integer.parseInt(row.getValue());
                    }
                }
            }
            catch (Exception e8) {
                e8.printStackTrace();
                System.err
                    .println("WARNING: please install SYS.SQLJUTL for appropriate treatement of PL/SQL default arguments.");
            }
        }
        finally {
            try {
                if (stmt != null) {
                    stmt.close();
                }
            }
            catch (SQLException e) {
                // Close resources, ignore exceptions.
            }
            try {
                if (rs != null) {
                    rs.close();
                }
            }
            catch (SQLException e) {
                // Close resources, ignore exceptions.
            }
        }
        if (hasDefaultInt == 1) {
            return true;
        }
        return false;
    }

    TypeClass[] generateDefaultArgsHolderParamTypes(TypeClass[] paramTypes, boolean[] paramDefaults,
        boolean[] ncharFormOfUse) throws SQLException, PublisherException {

        TypeClass[] defaultParamTypes = paramTypes;
        boolean hasDefault = false;
        for (int i = 0; i < paramDefaults.length; i++) {
            if (paramDefaults[i]) {
                hasDefault = true;
            }
        }
        if (hasDefault) {
            defaultParamTypes = new TypeClass[paramTypes.length];
            for (int i = 0; i < paramTypes.length; i++) {
                if (paramDefaults[i]) {
                    defaultParamTypes[i] = m_reflector.addDefaultArgsHolderType(
                        (SqlType)paramTypes[i], getSqlName().getSimpleName(), this,
                        ncharFormOfUse[i]);
                }
                else {
                    defaultParamTypes[i] = paramTypes[i];
                }
            }
        }
        return defaultParamTypes;
    }

    protected List<ProcedureMethod> m_methods;
    protected MethodFilter m_methodFilter = null;
}
