/*
 * 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: Jan 2012 - Initial implementation
package org.eclipse.persistence.tools.dbws.oracle;

import static org.eclipse.persistence.internal.helper.Helper.NL;
import static org.eclipse.persistence.tools.dbws.Util.COMMA;
import static org.eclipse.persistence.tools.dbws.Util.FLOAT_STR;
import static org.eclipse.persistence.tools.dbws.Util.INTEGER_STR;
import static org.eclipse.persistence.tools.dbws.Util.NUMERIC_STR;
import static org.eclipse.persistence.tools.dbws.Util.OTHER_STR;
import static org.eclipse.persistence.tools.dbws.Util.PERCENT;
import static org.eclipse.persistence.tools.dbws.Util.SEMICOLON;
import static org.eclipse.persistence.tools.dbws.Util.SINGLE_SPACE;
import static org.eclipse.persistence.tools.dbws.Util.UNDERSCORE;
import static org.eclipse.persistence.tools.dbws.Util.getJDBCTypeFromTypeName;
import static org.eclipse.persistence.tools.dbws.Util.getJDBCTypeNameFromType;

//javase imports
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

//EclipseLink imports
import org.eclipse.persistence.tools.oracleddl.metadata.CharType;
import org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseTypeWithEnclosedType;
import org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.FieldType;
import org.eclipse.persistence.tools.oracleddl.metadata.NumericType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCollectionType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLPackageType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLRecordType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLType;
import org.eclipse.persistence.tools.oracleddl.metadata.PrecisionType;
import org.eclipse.persistence.tools.oracleddl.metadata.ROWTYPEType;
import org.eclipse.persistence.tools.oracleddl.metadata.RawType;
import org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum;
import org.eclipse.persistence.tools.oracleddl.metadata.SizedType;
import org.eclipse.persistence.tools.oracleddl.metadata.TYPEType;
import org.eclipse.persistence.tools.oracleddl.metadata.TableType;
import org.eclipse.persistence.tools.oracleddl.metadata.VarChar2Type;
import org.eclipse.persistence.tools.oracleddl.metadata.VarCharType;
import org.eclipse.persistence.tools.oracleddl.metadata.visit.BaseDatabaseTypeVisitor;

public class ShadowDDLGenerator {

    static final String ROWTYPE_PREFIX = "_ROWTYPE_SQL";

    protected PLSQLPackageType plsqlPackageType;
    protected Map<String, Integer> rowTYPETypeCounts;
    protected Map<CompositeDatabaseTypeWithEnclosedType, DDLWrapper> createDDLs =
        new HashMap<CompositeDatabaseTypeWithEnclosedType, DDLWrapper>();
    protected Map<CompositeDatabaseTypeWithEnclosedType, DDLWrapper> dropDDLs =
        new HashMap<CompositeDatabaseTypeWithEnclosedType, DDLWrapper>();

    public ShadowDDLGenerator(PLSQLPackageType plsqlPackageType) {
        this.plsqlPackageType = plsqlPackageType;
        //count all the %ROWTYPE's and assign unique number
        CountROWTYPETypesVisitor countVisitor = new CountROWTYPETypesVisitor();
        plsqlPackageType.accept(countVisitor);
        rowTYPETypeCounts = countVisitor.getRowTYPETypeCounts();
        // visit all the PLSQLType's
        DDLWrapperGeneratorVisitor generatorVisitor = new DDLWrapperGeneratorVisitor();
        plsqlPackageType.accept(generatorVisitor);
    }

    public String getCreateDDLFor(CompositeDatabaseTypeWithEnclosedType dType) {
        return createDDLs.get(dType).ddl;
    }
    public List<String> getAllCreateDDLs() {
        List<String> allDDLs = new ArrayList<String>();
        for (Map.Entry<CompositeDatabaseTypeWithEnclosedType, DDLWrapper> me : createDDLs.entrySet()) {
            allDDLs.add(me.getValue().ddl);
        }
        return allDDLs;
    }

    public String getDropDDLFor(CompositeDatabaseTypeWithEnclosedType dType) {
        return dropDDLs.get(dType).ddl;
    }
    public List<String> getAllDropDDLs() {
        List<String> allDDLs = new ArrayList<String>();
        for (Map.Entry<CompositeDatabaseTypeWithEnclosedType, DDLWrapper> me : dropDDLs.entrySet()) {
            allDDLs.add(me.getValue().ddl);
        }
        return allDDLs;
    }

    protected String getShadowROWTYPETypeName(ROWTYPEType rowTYPEType) {
        return rowTYPEType.getTypeName().replace(PERCENT, UNDERSCORE);
    }

    static class CountROWTYPETypesVisitor extends BaseDatabaseTypeVisitor {
        Map<String, Integer> rowTYPETypeCounts = new HashMap<String, Integer>();
        int initialRowTYPETypeCount = 0;
        @Override
        public void beginVisit(ROWTYPEType rowTYPEType) {
            Integer rowTYPETypeCount = rowTYPETypeCounts.get(rowTYPEType.getTypeName());
            if (rowTYPETypeCount == null) {
                rowTYPETypeCounts.put(rowTYPEType.getTypeName(), initialRowTYPETypeCount++);
            }
        }
        public Map<String, Integer> getRowTYPETypeCounts() {
            return rowTYPETypeCounts;
        }
    }

    class DDLWrapperGeneratorVisitor extends BaseDatabaseTypeVisitor {
        static final String COR_TYPE = "CREATE OR REPLACE TYPE ";
        static final String DROP_TYPE = "DROP TYPE ";
        static final String FORCE = " FORCE";
        static final String LBRACKET = "(";
        static final String RBRACKET = ")";
        static final String SPACES = "      ";
        static final String AS_OBJECT = " AS OBJECT (";
        static final String AS_TABLE_OF = " AS TABLE OF ";
        static final String END_OBJECT = "\n);";
        static final String NUMBER_STR = "NUMBER";
        static final String ROWID_STR = "VARCHAR2(256)";
        static final String NUMBER_DEFAULTSIZE = "38";
        static final String FLOAT_DEFAULTSIZE = "63";
        static final String DOUBLE_DEFAULTSIZE = "126";
        static final String LONG_DEFAULTSIZE = "32760";
        protected Stack<PLSQLRecordType> recordTypes = new Stack<PLSQLRecordType>();
        protected Stack<ROWTYPEType> rowTYPETypes = new Stack<ROWTYPEType>();
        @Override
        public void beginVisit(PLSQLRecordType recordType) {
            if (recordTypes.isEmpty()) {
                recordTypes.push(recordType);
            }
            else if (!recordTypes.peek().equals(recordType)) {
                recordTypes.push(recordType);
            }
            DDLWrapper ddlWrapper = createDDLs.get(recordType);
            if (ddlWrapper == null) {
                ddlWrapper = new DDLWrapper();
                ddlWrapper.ddl = COR_TYPE + recordType.getParentType().getPackageName() + UNDERSCORE +
                    recordType.getTypeName().toUpperCase() + AS_OBJECT;
                createDDLs.put(recordType, ddlWrapper);
            }
        }
        @Override
        public void endVisit(PLSQLRecordType recordType) {
            recordTypes.pop();
            DDLWrapper ddlWrapper = createDDLs.get(recordType);
            if (ddlWrapper != null && !ddlWrapper.finished) {
                ddlWrapper.ddl += END_OBJECT;
                ddlWrapper.finished = true;
            }
            ddlWrapper = dropDDLs.get(recordType);
            if (ddlWrapper == null) {
                ddlWrapper = new DDLWrapper();
                ddlWrapper.ddl = DROP_TYPE + recordType.getParentType().getPackageName() + UNDERSCORE +
                    recordType.getTypeName().toUpperCase() + FORCE + SEMICOLON;
                ddlWrapper.finished = true;
                dropDDLs.put(recordType, ddlWrapper);
            }
        }
        @Override
        public void beginVisit(FieldType fieldType) {
            //skip fields from ObjectType's
            if (!recordTypes.isEmpty()) {
                PLSQLRecordType currentRecordType = recordTypes.peek();
                if (currentRecordType != null) {
                    DDLWrapper ddlWrapper = createDDLs.get(currentRecordType);
                    if (!ddlWrapper.finished) {
                        String fieldName = fieldType.getFieldName();
                        for (int i = 0, len = currentRecordType.getFields().size(); i < len; i++) {
                            FieldType f = currentRecordType.getFields().get(i);
                            if (fieldName.equals(f.getFieldName())) {
                                ddlWrapper.ddl += SPACES + fieldName + SINGLE_SPACE;
                                DatabaseType fieldDataType = f.getEnclosedType();
                                String fieldShadowName = null;
                                if (fieldDataType.isPLSQLType()) {
                                    fieldShadowName = ((PLSQLType)fieldDataType).getParentType().
                                        getPackageName() + UNDERSCORE + fieldDataType.
                                        getTypeName().toUpperCase();
                                } else if (fieldDataType.isTYPEType()) {
                                    fieldShadowName = getShadowTypeName(fieldDataType);
                                    TYPEType tType = (TYPEType) fieldDataType;
                                    if (tType.getEnclosedType().isFieldType()) {
                                        FieldType fType = (FieldType) tType.getEnclosedType();
                                        if (fType.getEnclosedType().isPrecisionType()) {
                                            PrecisionType pType = (PrecisionType) fType.getEnclosedType();
                                            long precision = pType.getPrecision();
                                            if (precision != pType.getDefaultPrecision()) {
                                                long scale = pType.getScale();
                                                if (scale != 0) {
                                                    fieldShadowName = fieldShadowName + LBRACKET + precision + COMMA + scale + RBRACKET;
                                                } else {
                                                    fieldShadowName = fieldShadowName + LBRACKET + precision + RBRACKET;
                                                }
                                            }
                                        } else if (fType.getEnclosedType().isSizedType()) {
                                            SizedType sType = (SizedType) fType.getEnclosedType();
                                            fieldShadowName = fieldShadowName + LBRACKET + sType.getSize() + RBRACKET;
                                        }
                                    }
                                } else {
                                    fieldShadowName = getShadowTypeName(fieldDataType);
                                }
                                ddlWrapper.ddl += fieldShadowName;
                                if (i < len -1) {
                                    ddlWrapper.ddl += COMMA + NL;
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
        @Override
        public void beginVisit(PLSQLCollectionType collectionType) {
            DDLWrapper ddlWrapper = createDDLs.get(collectionType);
            if (ddlWrapper == null) {
                ddlWrapper = new DDLWrapper();
            }
            if (!ddlWrapper.finished) {
                String shadowNestedTypeName = null;
                DatabaseType nestedType = collectionType.getEnclosedType();
                if (nestedType.isNumericType()) {
                    NumericType nDataType = (NumericType)nestedType;
                    if (nDataType.isNumberSynonym()) {
                        shadowNestedTypeName = NUMBER_STR;
                    }
                    else {
                        shadowNestedTypeName = NUMERIC_STR;
                    }
                    PrecisionType pDataType = (PrecisionType)nestedType;
                    long defaultPrecision = pDataType.getDefaultPrecision();
                    long precision = pDataType.getPrecision();
                    long scale = pDataType.getScale();
                    if (precision != defaultPrecision) {
                        shadowNestedTypeName += LBRACKET + precision;
                        if (scale != 0) {
                            shadowNestedTypeName += COMMA + SINGLE_SPACE + scale;
                        }
                        shadowNestedTypeName += RBRACKET;
                    }
                }
                else {
                    shadowNestedTypeName = getShadowTypeName(nestedType);
                }
                ddlWrapper.ddl = COR_TYPE + collectionType.getParentType().getPackageName() +
                    UNDERSCORE + collectionType.getTypeName().toUpperCase() + AS_TABLE_OF +
                        shadowNestedTypeName + SEMICOLON;
                ddlWrapper.finished = true;
                createDDLs.put(collectionType, ddlWrapper);
            }
        }
        @Override
        public void endVisit(PLSQLCollectionType collectionType) {
            DDLWrapper ddlWrapper = new DDLWrapper();
            ddlWrapper.ddl = DROP_TYPE + collectionType.getParentType().getPackageName() + UNDERSCORE +
                collectionType.getTypeName().toUpperCase() + FORCE + SEMICOLON;
            ddlWrapper.finished = true;
            dropDDLs.put(collectionType, ddlWrapper);
        }
        @Override
        public void beginVisit(ROWTYPEType rowTYPEType) {
            if (rowTYPETypes.isEmpty()) {
                rowTYPETypes.push(rowTYPEType);
            }
            else if (!rowTYPETypes.peek().equals(rowTYPEType)) {
                rowTYPETypes.push(rowTYPEType);
            }
            DDLWrapper ddlWrapper = createDDLs.get(rowTYPEType);
            if (ddlWrapper == null) {
                ddlWrapper = new DDLWrapper();
                ddlWrapper.ddl = COR_TYPE + getShadowROWTYPETypeName(rowTYPEType) + AS_OBJECT;
                //manually 'crawl' thru %ROWTYPE to TableType to columns and build up type fields
                DatabaseType enclosedType = rowTYPEType.getEnclosedType();
                if (enclosedType.isTableType()) {
                    TableType tableType =  (TableType)enclosedType;
                    ddlWrapper.ddl += NL;
                    for (int i = 0, len = tableType.getColumns().size(); i < len; i++) {
                        FieldType f = tableType.getColumns().get(i);
                        ddlWrapper.ddl += SPACES + f.getFieldName() + SINGLE_SPACE;
                        DatabaseType fieldDataType = f.getEnclosedType();
                        String fieldShadowName = getShadowTypeName(fieldDataType);
                        ddlWrapper.ddl += fieldShadowName;
                        if (i < len -1) {
                            ddlWrapper.ddl += COMMA + NL;
                        }
                    }
                    createDDLs.put(rowTYPEType, ddlWrapper);
                }
                /*
                else {
                   //Huh? a %ROWTYPE that points to something other than a TableType?
                   //ignore for now
                }
                 */
            }
        }
        @Override
        public void endVisit(ROWTYPEType rowTYPEType) {
            rowTYPETypes.pop();
            DDLWrapper ddlWrapper = createDDLs.get(rowTYPEType);
            if (ddlWrapper != null && !ddlWrapper.finished) {
                ddlWrapper.ddl += END_OBJECT;
                ddlWrapper.finished = true;
            }
            ddlWrapper = dropDDLs.get(rowTYPEType);
            if (ddlWrapper == null) {
                ddlWrapper = new DDLWrapper();
                ddlWrapper.ddl = DROP_TYPE + getShadowROWTYPETypeName(rowTYPEType) + FORCE + SEMICOLON;
                ddlWrapper.finished = true;
                dropDDLs.put(rowTYPEType, ddlWrapper);
            }
        }

        protected String getShadowTypeName(DatabaseType dataType ) {
            String shadowTypeName = null;
            if (dataType == ScalarDatabaseTypeEnum.INTEGER_TYPE ||
                dataType == ScalarDatabaseTypeEnum.SMALLINT_TYPE) {
                shadowTypeName = NUMBER_STR + LBRACKET + NUMBER_DEFAULTSIZE + RBRACKET;
            }
            else if (dataType == ScalarDatabaseTypeEnum.BINARY_INTEGER_TYPE ||
                dataType == ScalarDatabaseTypeEnum.BOOLEAN_TYPE ||
                dataType == ScalarDatabaseTypeEnum.NATURAL_TYPE ||
                dataType == ScalarDatabaseTypeEnum.PLS_INTEGER_TYPE ||
                dataType == ScalarDatabaseTypeEnum.POSITIVE_TYPE ||
                dataType == ScalarDatabaseTypeEnum.SIGN_TYPE ||
                dataType == ScalarDatabaseTypeEnum.SIMPLE_INTEGER_TYPE) {
                shadowTypeName = INTEGER_STR;
            }
            else if (dataType == ScalarDatabaseTypeEnum.ROWID_TYPE) {
                shadowTypeName = ROWID_STR;
            }
            else if (dataType == ScalarDatabaseTypeEnum.SIMPLE_DOUBLE_TYPE) {
                shadowTypeName = ScalarDatabaseTypeEnum.BINARY_DOUBLE_TYPE.getTypeName();
            }
            else if (dataType == ScalarDatabaseTypeEnum.SIMPLE_FLOAT_TYPE) {
                shadowTypeName = ScalarDatabaseTypeEnum.BINARY_FLOAT_TYPE.getTypeName();
            }
            else if (dataType.isPrecisionType()) {
                PrecisionType pDataType = (PrecisionType)dataType;
                long defaultPrecision = pDataType.getDefaultPrecision();
                String defaultPrecisionStr = NUMBER_DEFAULTSIZE;
                if (dataType.isNumericType() || dataType.isDecimalType()) {
                    shadowTypeName = NUMBER_STR;
                }
                else {
                    shadowTypeName = FLOAT_STR;
                    defaultPrecisionStr = FLOAT_DEFAULTSIZE;
                    if (dataType.isFloatType() || dataType.isDoubleType()) {
                        defaultPrecisionStr = DOUBLE_DEFAULTSIZE;
                    }
                }
                if (!(dataType.isNumericType() && ((NumericType)dataType).isNumberSynonym())) {
                    long precision = pDataType.getPrecision();
                    long scale = pDataType.getScale();
                    if (precision != defaultPrecision) {
                        shadowTypeName += LBRACKET + precision;
                        if (scale != 0) {
                            shadowTypeName += COMMA + SINGLE_SPACE + scale;
                        }
                    }
                    else {
                        shadowTypeName += LBRACKET + defaultPrecisionStr;
                    }
                    shadowTypeName += RBRACKET;
                }
            }
            else if (dataType.isVarCharType()) {
                shadowTypeName = VarChar2Type.TYPENAME;
                VarCharType vcharType = (VarCharType)dataType;
                long defaultSize = vcharType.getDefaultSize();
                long size = vcharType.getSize();
                String sizeStr = Long.toString(size);
                if (dataType.isLongType()) {
                    shadowTypeName = VarChar2Type.TYPENAME;
                    if (size == defaultSize) {
                        sizeStr = LONG_DEFAULTSIZE;
                    }
                }
                shadowTypeName += LBRACKET + sizeStr + RBRACKET;
            }
            else if (dataType.isCharType()) {
                shadowTypeName = CharType.TYPENAME;
                long size = ((CharType)dataType).getSize();
                shadowTypeName += LBRACKET + size + RBRACKET;
            }
            else if (dataType.isSizedType()) {
                shadowTypeName = dataType.getTypeName();
                SizedType sDataType = (SizedType)dataType;
                long defaultSize = sDataType.getDefaultSize();
                String sizeStr = null;
                long size = sDataType.getSize();
                if (dataType.isLongType()) {
                    shadowTypeName = VarChar2Type.TYPENAME;
                    if (size == defaultSize) {
                        sizeStr = LONG_DEFAULTSIZE;
                    }
                    else {
                        sizeStr = Long.toString(size);
                    }
                    shadowTypeName += LBRACKET + sizeStr + RBRACKET;
                }
                else if (dataType.isLongRawType()) {
                    shadowTypeName = RawType.TYPENAME;
                    if (size == defaultSize) {
                        sizeStr = LONG_DEFAULTSIZE;
                    }
                    else {
                        sizeStr = Long.toString(size);
                    }
                    shadowTypeName += LBRACKET + sizeStr + RBRACKET;
                }
                else if (size != defaultSize) {
                    shadowTypeName += LBRACKET + size + RBRACKET;
                }
            }
            else if (dataType.isPLSQLType()) {
                shadowTypeName = ((PLSQLType)dataType).getParentType().getPackageName() +
                    UNDERSCORE + dataType.getTypeName();
            }
            else {
                String typeName = dataType.getTypeName();
                int typ = getJDBCTypeFromTypeName(typeName);
                shadowTypeName = getJDBCTypeNameFromType(typ);
                if (OTHER_STR.equals(shadowTypeName)) {
                    shadowTypeName = typeName;
                }
            }
            return shadowTypeName;
        }
    }
    static class DDLWrapper {
        String ddl;
        boolean finished = false;
        @Override
        public String toString() {
            return ddl;
        }
    }
}
