/*****************************************************************
 *   Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 ****************************************************************/

package org.apache.cayenne.modeler.editor.dbimport;

import org.apache.cayenne.dbsync.reverse.dbimport.Catalog;
import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeColumn;
import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeProcedure;
import org.apache.cayenne.dbsync.reverse.dbimport.ExcludeTable;
import org.apache.cayenne.dbsync.reverse.dbimport.IncludeColumn;
import org.apache.cayenne.dbsync.reverse.dbimport.IncludeProcedure;
import org.apache.cayenne.dbsync.reverse.dbimport.IncludeTable;
import org.apache.cayenne.dbsync.reverse.dbimport.ReverseEngineering;
import org.apache.cayenne.dbsync.reverse.dbimport.Schema;
import org.apache.cayenne.modeler.dialog.db.load.DbImportTreeNode;

import javax.swing.tree.TreePath;
import java.awt.Color;

/**
 * @since 4.1
 */
class DbImportNodeHandler {

    private static final Color ACCEPT_COLOR = new Color(60,179,113);
    private static final Color EXCLUDE_COLOR = new Color(178, 0, 0);
    static final Color NON_INCLUDE_COLOR = Color.LIGHT_GRAY;
    static final Color LABEL_COLOR = Color.BLACK;
    private static final int EXCLUDE_TABLE_RATE = -10000;

    private boolean existFirstLevelIncludeTable;
    private boolean existCatalogsOrSchemas;
    private boolean hasEntitiesInEmptyContainer;
    private DbImportTreeNode dbSchemaNode;
    private DbImportTree reverseEngineeringTree;

    private boolean namesIsEqual(DbImportTreeNode reverseEngineeringNode) {
        if (isContainer(reverseEngineeringNode)) {
            return dbSchemaNode.getSimpleNodeName().equals(reverseEngineeringNode.getSimpleNodeName());
        } else {
            return (dbSchemaNode.getSimpleNodeName().toLowerCase().matches(reverseEngineeringNode.getSimpleNodeName().toLowerCase()));
        }
    }

    boolean isContainer(DbImportTreeNode node) {
        return (node.getUserObject().getClass() == Schema.class) || (node.getUserObject().getClass() == Catalog.class);
    }

    private boolean isEmptyContainer(DbImportTreeNode rootNode) {
        return ((getChildIncludeTableCount(rootNode) == 0) && (!existFirstLevelIncludeTable));
    }

    boolean isParentIncluded() {
        return ((dbSchemaNode.getParent() != null) && (((DbImportTreeNode) dbSchemaNode.getParent()).isColorized()));
    }

    // Compare node with current rendered node
    public boolean nodesIsEqual(DbImportTreeNode reverseEngineeringNode) {
        TreePath[] paths = reverseEngineeringTree.getSelectionPaths();
        for (TreePath path : paths != null ? paths : new TreePath[0]) {
            DbImportTreeNode node = (DbImportTreeNode) path.getLastPathComponent();
            if ((nodesClassesComparation(node.getUserObject().getClass(), dbSchemaNode.getUserObject().getClass()))
                    && namesIsEqual(node)
                    && (dbSchemaNode.getLevel() >= node.getLevel())
                    && (dbSchemaNode.parentsIsEqual(node))) {
                return true;
            }
        }
        if ((nodesClassesComparation(reverseEngineeringNode.getUserObject().getClass(), dbSchemaNode.getUserObject().getClass()))
                && namesIsEqual(reverseEngineeringNode)
                && (dbSchemaNode.getLevel() >= reverseEngineeringNode.getLevel())
                && (dbSchemaNode.parentsIsEqual(reverseEngineeringNode))) {
            return true;
        }
        return false;
    }

    public boolean checkTreesLevels(DbImportTree dbTree) {
        if (dbTree.getRootNode().getChildCount() == 0) {
            return false;
        }
        DbImportTreeNode dbNode = (DbImportTreeNode) dbTree.getRootNode().getChildAt(0);
        int childCount = reverseEngineeringTree.getRootNode().getChildCount();
        for (int i = 0; i < childCount; i++) {
            if (((DbImportTreeNode) reverseEngineeringTree.getRootNode().getChildAt(i)).
                    getUserObject().getClass() == Catalog.class) {
                if (dbNode.getUserObject().getClass() == Catalog.class || dbNode.getUserObject().getClass() == IncludeTable.class) {
                    return true;
                } else {
                    return false;
                }
            }
        }
        return true;
    }

    // Compare reverseEngineeringNode with node.getParent()
    private boolean compareWithParent(DbImportTreeNode reverseEngineeringNode) {
        if ((reverseEngineeringNode == null) || (dbSchemaNode.getParent() == null)) {
            return false;
        }
        if ((((DbImportTreeNode)dbSchemaNode.getParent()).getUserObject().getClass() == reverseEngineeringNode.getUserObject().getClass())
                && (((DbImportTreeNode)dbSchemaNode.getParent()).getSimpleNodeName().equals(reverseEngineeringNode.getSimpleNodeName()))
                && (((DbImportTreeNode)dbSchemaNode.getParent()).getLevel() >= reverseEngineeringNode.getLevel())
                && (((DbImportTreeNode)dbSchemaNode.getParent())).parentsIsEqual(reverseEngineeringNode)) {
            return true;
        }
        return false;
    }

    // Get child IncludeTable's count in node, if exists
    private int getChildIncludeTableCount(DbImportTreeNode parentNode) {
        if (parentNode.isIncludeTable()) {
            return 1;
        }
        int childCount = parentNode.getChildCount();
        int result = 0;
        for (int i = 0; i < childCount; i++) {
            DbImportTreeNode tmpNode = (DbImportTreeNode) parentNode.getChildAt(i);
            if (tmpNode.isIncludeTable()) {
                result++;
            }
        }
        return result;
    }

    // Find Exclude-node in configuration
    private boolean foundExclude(DbImportTreeNode rootNode) {
        int childCount = rootNode.getChildCount();
        for (int i = 0; i < childCount; i++) {
            DbImportTreeNode tmpNode = (DbImportTreeNode) rootNode.getChildAt(i);
            if (tmpNode.getChildCount() > 0) {
                if (tmpNode.isExcludeTable() || tmpNode.isExcludeProcedure()) {
                    return true;
                }
            }
            if (dbSchemaNode.getParent() != null) {
                if (nodesIsEqual(tmpNode)) {
                    if (tmpNode.isExcludeTable() || tmpNode.isExcludeProcedure()) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /*
    *  Recursively traverse DbImportTree,
    *  Increment result if rendered node exists in configuration tree,
    *  Subtract EXCLUDE_TABLE_RATE from result, if found Exclude-node for rendered node,
    *  Return 0, if rendered node not found.
    */
    int traverseTree(DbImportTreeNode rootNode) {
        hasEntitiesInEmptyContainer = false;
        int traverseResult = 0;
        int childCount = rootNode.getChildCount();
        boolean hasProcedures = false;

        // Case for empty reverse engineering, which has a include/exclude tables/procedures
        if ((childCount == 0) && (nodesIsEqual(rootNode))) {
            traverseResult++;
        }

        if (nodesIsEqual(rootNode)) {
            traverseResult++;
        }

        ReverseEngineering reverseEngineering = reverseEngineeringTree.getReverseEngineering();
        if ((reverseEngineering.getCatalogs().isEmpty()) && (reverseEngineering.getSchemas().isEmpty())
                && (reverseEngineering.getIncludeTables().isEmpty())
                && (!dbSchemaNode.isIncludeProcedure())) {
            traverseResult++;
        }

        if (nodesIsEqual(rootNode) && isEmptyContainer(rootNode)) {
            hasEntitiesInEmptyContainer = true;
            if (foundExclude(rootNode)) {
                return EXCLUDE_TABLE_RATE;
            }
            return 1;
        }

        if (compareWithParent(rootNode) && (!rootNode.isReverseEngineering()) &&
                isEmptyContainer(rootNode) && (dbSchemaNode.isIncludeTable())) {
            hasEntitiesInEmptyContainer = true;
            if (foundExclude(rootNode)) {
                return EXCLUDE_TABLE_RATE;
            }
            return 1;
        }

        if (hasEntitiesInEmptyContainer) {
            for (int i = 0; i < childCount; i++) {
                DbImportTreeNode tmpNode = (DbImportTreeNode) rootNode.getChildAt(i);
                if (dbSchemaNode.isIncludeProcedure() && (nodesIsEqual(tmpNode))) {
                    int tmpNodeChildCount = tmpNode.getChildCount();
                    if (tmpNodeChildCount > 0) {
                        traverseResult += traverseTree((DbImportTreeNode) rootNode.getChildAt(i));
                    }
                    traverseResult++;
                    hasProcedures = true;
                }
            }
            if ((!rootNode.isExcludeTable()) && (!nodesIsEqual(rootNode))
                    && (!dbSchemaNode.isIncludeProcedure()) &&(!dbSchemaNode.isIncludeColumn())) {
                traverseResult++;
            } else {
                if ((!hasProcedures) && (!dbSchemaNode.isIncludeProcedure())) {
                    traverseResult += EXCLUDE_TABLE_RATE;
                }
            }
        }

        for (int i = 0; i < childCount; i++) {
            DbImportTreeNode tmpNode = (DbImportTreeNode) rootNode.getChildAt(i);
            if (tmpNode.getChildCount() > 0) {
                traverseResult += traverseTree(tmpNode);
                if (tmpNode.isExcludeTable() || tmpNode.isExcludeProcedure()) {
                    traverseResult += EXCLUDE_TABLE_RATE;
                }
            } else if (compareWithParent(tmpNode) && !(existFirstLevelIncludeTable)) {
                if (!dbSchemaNode.isIncludeProcedure()) {
                    traverseResult++;
                }
            }
            if (dbSchemaNode.getParent() != null) {
                if (nodesIsEqual(tmpNode)) {
                    if (tmpNode.isExcludeTable() || tmpNode.isExcludeProcedure()) {
                        traverseResult += EXCLUDE_TABLE_RATE;
                    }
                    traverseResult++;
                }
            }
        }
        return traverseResult;
    }

    Color getColorByNodeType(DbImportTreeNode node) {
        if ((reverseEngineeringTree.getSelectionPaths() != null) &&(reverseEngineeringTree.getSelectionPaths().length > 1)) {
            for (TreePath path : reverseEngineeringTree.getSelectionPaths()) {
                DbImportTreeNode pathNode = (DbImportTreeNode) path.getLastPathComponent();
                if (pathNode.getSimpleNodeName().equals(dbSchemaNode.getSimpleNodeName())) {
                    if (pathNode.isExcludeTable() || pathNode.isExcludeProcedure() || node.isExcludeColumn()) {
                        return EXCLUDE_COLOR;
                    } else {
                        return ACCEPT_COLOR;
                    }
                }
            }
        }
        if (node.isExcludeTable() || node.isExcludeProcedure() || node.isExcludeColumn()) {
            return EXCLUDE_COLOR;
        } else {
            return ACCEPT_COLOR;
        }
    }

    void findFirstLevelIncludeTable() {
        DbImportTreeNode root = reverseEngineeringTree.getRootNode();
        int childCount = root.getChildCount();
        existFirstLevelIncludeTable = false;
        existCatalogsOrSchemas = false;
        for (int i = 0; i < childCount; i++) {
            DbImportTreeNode tmpNode = (DbImportTreeNode) root.getChildAt(i);
            if (tmpNode.isIncludeTable()) {
                existFirstLevelIncludeTable = true;
            }
            if (isContainer(tmpNode)) {
                existCatalogsOrSchemas = true;
            }
        }
    }

    // Check, is DatabaseTree started with IncludeTable or IncludeProcedure
    boolean isFirstNodeIsPrimitive(DbImportTree tree) {
        final int firstChildIndex = 0;
        DbImportTreeNode root = tree.getRootNode();
        if (root.getChildCount() == 0) {
            return false;
        }
        DbImportTreeNode firstElement = (DbImportTreeNode) root.getChildAt(firstChildIndex);
        if (firstElement.isIncludeTable() || firstElement.isIncludeProcedure()) {
            return true;
        }
        return false;
    }

    public boolean nodesClassesComparation(Class firstClass, Class secondClass) {
        if (firstClass.equals(secondClass)) {
            return true;
        }
        if ((firstClass.equals(IncludeTable.class)) && (secondClass.equals(ExcludeTable.class))) {
            return true;
        }
        if ((firstClass.equals(ExcludeTable.class)) && (secondClass.equals(IncludeTable.class))) {
            return true;
        }
        if ((firstClass.equals(IncludeProcedure.class)) && (secondClass.equals(ExcludeProcedure.class))) {
            return true;
        }
        if ((firstClass.equals(ExcludeProcedure.class)) && (secondClass.equals(IncludeProcedure.class))) {
            return true;
        }
        if ((firstClass.equals(ExcludeColumn.class)) && (secondClass.equals(IncludeColumn.class))) {
            return true;
        }
        if ((firstClass.equals(IncludeColumn.class)) && (secondClass.equals(ExcludeColumn.class))) {
            return true;
        }
        return false;
    }

    public boolean isExistCatalogsOrSchemas() {
        return existCatalogsOrSchemas;
    }

    public boolean getHasEntitiesInEmptyContainer() {
        return hasEntitiesInEmptyContainer;
    }

    public void setHasEntitiesInEmptyContainer(boolean newFlag) {
        hasEntitiesInEmptyContainer = newFlag;
    }

    public void setDbSchemaNode(DbImportTreeNode dbSchemaNode) {
        this.dbSchemaNode = dbSchemaNode;
    }

    public void setReverseEngineeringTree(DbImportTree reverseEngineeringTree) {
        this.reverseEngineeringTree = reverseEngineeringTree;
    }
}
