/**
 * 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
 *
 *     http://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.
 */
import Enums from "../Enums";
import { curveBasis } from "d3-shape";

const DataUtils = {
    /**
     * [getBaseUrl description]
     * @param  {[type]} url [description]
     * @return {[type]}     [description]
     */
    getBaseUrl: function(url) {
        return url.replace(/\/[\w-]+.(jsp|html)|\/+$/gi, "");
    },
    /**
     * [getEntityIconPath description]
     * @param  {[type]} options.entityData [description]
     * @param  {Object} options.errorUrl   }            [description]
     * @return {[type]}                    [description]
     */
    getEntityIconPath: function({ entityData, errorUrl } = {}) {
        var serviceType,
            status,
            typeName,
            iconBasePath = this.getBaseUrl(window.location.pathname) + Globals.entityImgPath;
        if (entityData) {
            typeName = entityData.typeName;
            serviceType = entityData && entityData.serviceType;
            status = entityData && entityData.status;
        }

        function getImgPath(imageName) {
            return iconBasePath + (Enums.entityStateReadOnly[status] ? "disabled/" + imageName : imageName);
        }

        function getDefaultImgPath() {
            if (entityData.isProcess) {
                if (Enums.entityStateReadOnly[status]) {
                    return iconBasePath + "disabled/process.png";
                } else {
                    return iconBasePath + "process.png";
                }
            } else {
                if (Enums.entityStateReadOnly[status]) {
                    return iconBasePath + "disabled/table.png";
                } else {
                    return iconBasePath + "table.png";
                }
            }
        }

        if (entityData) {
            if (errorUrl) {
                var isErrorInTypeName = errorUrl && errorUrl.match("entity-icon/" + typeName + ".png|disabled/" + typeName + ".png") ? true : false;
                if (serviceType && isErrorInTypeName) {
                    var imageName = serviceType + ".png";
                    return getImgPath(imageName);
                } else {
                    return getDefaultImgPath();
                }
            } else if (entityData.typeName) {
                var imageName = entityData.typeName + ".png";
                return getImgPath(imageName);
            } else {
                return getDefaultImgPath();
            }
        }
    },
    /**
     * [isProcess description]
     * @param  {[type]}  options.typeName   [description]
     * @param  {[type]}  options.superTypes [description]
     * @param  {[type]}  options.entityDef  [description]
     * @return {Boolean}                    [description]
     */
    isProcess: function({ typeName, superTypes, entityDef }) {
        if (typeName == "Process") {
            return true;
        }
        return superTypes.indexOf("Process") > -1;
    },
    /**
     * [isDeleted description]
     * @param  {[type]}  node [description]
     * @return {Boolean}      [description]
     */
    isDeleted: function(node) {
        if (node === undefined) {
            return;
        }
        return Enums.entityStateReadOnly[node.status];
    },
    isNodeToBeUpdated: function(node, filterObj) {
        var isProcessHideCheck = filterObj.isProcessHideCheck,
            isDeletedEntityHideCheck = filterObj.isDeletedEntityHideCheck;
        var returnObj = {
            isProcess: isProcessHideCheck && node.isProcess,
            isDeleted: isDeletedEntityHideCheck && node.isDeleted
        };
        returnObj["update"] = returnObj.isProcess || returnObj.isDeleted;
        if (node.label === "Expand") {
            returnObj["update"] = true;
        }
        return returnObj;
    },
    /**
     * [getServiceType description]
     * @param  {[type]} options.typeName  [description]
     * @param  {[type]} options.entityDef [description]
     * @return {[type]}                   [description]
     */
    getServiceType: function({ typeName, entityDef }) {
        var serviceType = null;
        if (typeName) {
            if (entityDef) {
                serviceType = entityDef.serviceType || null;
            }
        }
        return serviceType;
    },
    /**
     * [getEntityDef description]
     * @param  {[type]} options.typeName            [description]
     * @param  {[type]} options.entityDefCollection [description]
     * @return {[type]}                             [description]
     */
    getEntityDef: function({ typeName, entityDefCollection }) {
        var entityDef = null;
        if (typeName) {
            entityDef = entityDefCollection.find(function(obj) {
                return obj.name == typeName;
            });
        }
        return entityDef;
    },
    /**
     * [getNestedSuperTypes description]
     * @param  {[type]} options.entityDef           [description]
     * @param  {[type]} options.entityDefCollection [description]
     * @return {[type]}                             [description]
     */
    getNestedSuperTypes: function({ entityDef, entityDefCollection }) {
        var data = entityDef,
            collection = entityDefCollection,
            superTypes = new Set();

        var getData = function(data, collection) {
            if (data) {
                if (data.superTypes && data.superTypes.length) {
                    data.superTypes.forEach(function(superTypeName) {
                        superTypes.add(superTypeName);
                        var collectionData = collection.find(function(obj) {
                            obj.name === superTypeName;
                        });
                        if (collectionData) {
                            getData(collectionData, collection);
                        }
                    });
                }
            }
        };
        getData(data, collection);
        return Array.from(superTypes);
    },
    generateData: function({ data = {}, filterObj, entityDefCollection, g, guid, setGraphEdge, setGraphNode }) {
        return new Promise((resolve, reject) => {
            try {
                var relations = data.relations || {},
                    guidEntityMap = data.guidEntityMap || {},
                    isHideFilterOn = filterObj.isProcessHideCheck || filterObj.isDeletedEntityHideCheck,
                    newHashMap = {},
                    styleObj = {
                        fill: "none",
                        stroke: "#ffb203",
                        width: 3
                    },
                    makeNodeData = (relationObj) => {
                        if (relationObj) {
                            if (relationObj.updatedValues) {
                                return relationObj;
                            }
                            var nodeLabel = relationObj.displayText ? relationObj.displayText : " ",
                                obj = Object.assign(relationObj, {
                                    shape: "img",
                                    updatedValues: true,
                                    label: nodeLabel.trunc(18),
                                    toolTipLabel: nodeLabel,
                                    id: relationObj.guid,
                                    isLineage: true,
                                    isIncomplete: relationObj.isIncomplete,
                                    entityDef: this.getEntityDef({ typeName: relationObj.typeName, entityDefCollection })
                                });
                            obj["serviceType"] = this.getServiceType(obj);
                            obj["superTypes"] = this.getNestedSuperTypes({
                                ...obj,
                                entityDefCollection: entityDefCollection
                            });
                            obj["isProcess"] = this.isProcess(obj);
                            obj["isDeleted"] = this.isDeleted(obj);
                            return obj;
                        }
                    },
                    crateLineageRelationshipHashMap = function({ relations } = {}) {
                        var newHashMap = {};
                        relations.forEach(function(obj) {
                            if (newHashMap[obj.fromEntityId]) {
                                newHashMap[obj.fromEntityId].push(obj.toEntityId);
                            } else {
                                newHashMap[obj.fromEntityId] = [obj.toEntityId];
                            }
                        });
                        return newHashMap;
                    },
                    getStyleObjStr = function(styleObj) {
                        return "fill:" + styleObj.fill + ";stroke:" + styleObj.stroke + ";stroke-width:" + styleObj.width;
                    },
                    getNewToNodeRelationship = (toNodeGuid, filterObj) => {
                        if (toNodeGuid && relationshipMap[toNodeGuid]) {
                            var newRelationship = [];
                            relationshipMap[toNodeGuid].forEach((guid) => {
                                var nodeToBeUpdated = this.isNodeToBeUpdated(makeNodeData(guidEntityMap[guid]), filterObj);
                                if (nodeToBeUpdated.update) {
                                    var newRelation = getNewToNodeRelationship(guid, filterObj);
                                    if (newRelation) {
                                        newRelationship = newRelationship.concat(newRelation);
                                    }
                                } else {
                                    newRelationship.push(guid);
                                }
                            });
                            return newRelationship;
                        } else {
                            return null;
                        }
                    },
                    getToNodeRelation = (toNodes, fromNodeToBeUpdated, filterObj) => {
                        var toNodeRelationship = [];
                        toNodes.forEach((toNodeGuid) => {
                            var toNodeToBeUpdated = this.isNodeToBeUpdated(makeNodeData(guidEntityMap[toNodeGuid]), filterObj);
                            if (toNodeToBeUpdated.update) {
                                // To node need to updated
                                if (pendingFromRelationship[toNodeGuid]) {
                                    toNodeRelationship = toNodeRelationship.concat(pendingFromRelationship[toNodeGuid]);
                                } else {
                                    var newToNodeRelationship = getNewToNodeRelationship(toNodeGuid, filterObj);
                                    if (newToNodeRelationship) {
                                        toNodeRelationship = toNodeRelationship.concat(newToNodeRelationship);
                                    }
                                }
                            } else {
                                //when bothe node not to be updated.
                                toNodeRelationship.push(toNodeGuid);
                            }
                        });
                        return toNodeRelationship;
                    },
                    setNode = (guid) => {
                        if (!g._nodes[guid]) {
                            var nodeData = makeNodeData(guidEntityMap[guid]);
                            setGraphNode(guid, nodeData);
                            return nodeData;
                        } else {
                            return g._nodes[guid];
                        }
                    },
                    setEdge = function(fromNodeGuid, toNodeGuid, opt = {}) {
                        setGraphEdge(fromNodeGuid, toNodeGuid, {
                            arrowhead: "arrowPoint",
                            curve: curveBasis,
                            style: getStyleObjStr(styleObj),
                            styleObj: styleObj,
                            ...opt
                        });
                    },
                    setGraphData = function(fromEntityId, toEntityId) {
                        setNode(fromEntityId);
                        setNode(toEntityId);
                        setEdge(fromEntityId, toEntityId);
                    },
                    pendingFromRelationship = {};
                if (isHideFilterOn) {
                    var relationshipMap = crateLineageRelationshipHashMap(data);
                    Object.keys(relationshipMap).forEach((fromNodeGuid) => {
                        var toNodes = relationshipMap[fromNodeGuid],
                            fromNodeToBeUpdated = this.isNodeToBeUpdated(makeNodeData(guidEntityMap[fromNodeGuid]), filterObj),
                            toNodeList = getToNodeRelation(toNodes, fromNodeToBeUpdated, filterObj);
                        if (fromNodeToBeUpdated.update) {
                            if (pendingFromRelationship[fromNodeGuid]) {
                                pendingFromRelationship[fromNodeGuid] = pendingFromRelationship[fromNodeGuid].concat(toNodeList);
                            } else {
                                pendingFromRelationship[fromNodeGuid] = toNodeList;
                            }
                        } else {
                            toNodeList.forEach(function(toNodeGuid) {
                                setGraphData(fromNodeGuid, toNodeGuid);
                            });
                        }
                    });
                } else {
                    if (relations.length) {
                        relations.forEach(function(obj) {
                            setGraphData(obj.fromEntityId, obj.toEntityId);
                        });
                    } else {
                        setNode(guid);
                    }
                }
                if (g._nodes[guid]) {
                    if (g._nodes[guid]) {
                        g._nodes[guid]["isLineage"] = false;
                    }
                    this.findImpactNodeAndUpdateData({
                        guid,
                        g,
                        setEdge,
                        getStyleObjStr
                    });
                }
                if (!g._nodes[guid]) {
                    setNode(guid);
                }
                resolve(g);
            } catch (e) {
                reject(e);
            }
        });
    },
    findImpactNodeAndUpdateData: function({ guid, getStyleObjStr, g, setEdge }) {
        var that = this,
            traversedMap = {},
            styleObj = {
                fill: "none",
                stroke: "#fb4200",
                width: 3
            },
            traversed = function(toNodeList = {}, fromNodeGuid) {
                let toNodeKeyList = Object.keys(toNodeList);
                if (toNodeKeyList.length) {
                    if (!traversedMap[fromNodeGuid]) {
                        traversedMap[fromNodeGuid] = true;
                        toNodeKeyList.forEach(function(toNodeGuid) {
                            if (g._nodes[toNodeGuid]) {
                                g._nodes[toNodeGuid]["isLineage"] = false;
                            }
                            setEdge(fromNodeGuid, toNodeGuid, {
                                style: getStyleObjStr(styleObj),
                                styleObj: styleObj
                            });
                            traversed(g._sucs[toNodeGuid], toNodeGuid);
                        });
                    }
                }
            };
        traversed(g._sucs[guid], guid);
    }
};
export default DataUtils;