/**
 * 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.
 */
package org.apache.atlas.repository.store.graph.v1;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;

import static org.apache.atlas.repository.Constants.TYPE_CATEGORY_PROPERTY_KEY;
import static org.apache.atlas.repository.Constants.VERTEX_TYPE_PROPERTY_KEY;
import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.VERTEX_TYPE;

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.listener.TypeDefChangeListener;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.AtlasClassificationDefStore;
import org.apache.atlas.repository.store.graph.AtlasEntityDefStore;
import org.apache.atlas.repository.store.graph.AtlasEnumDefStore;
import org.apache.atlas.repository.store.graph.AtlasRelationshipDefStore;
import org.apache.atlas.repository.store.graph.AtlasStructDefStore;
import org.apache.atlas.repository.store.graph.AtlasTypeDefGraphStore;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;


/**
 * Graph persistence store for TypeDef - v1
 */
@Singleton
@Component
public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
    private static final Logger LOG = LoggerFactory.getLogger(AtlasTypeDefGraphStoreV1.class);

    protected final AtlasGraph atlasGraph;

    @Inject
    public AtlasTypeDefGraphStoreV1(AtlasTypeRegistry typeRegistry,
                                    Set<TypeDefChangeListener> typeDefChangeListeners,
                                    AtlasGraph atlasGraph) {
        super(typeRegistry, typeDefChangeListeners);
        this.atlasGraph = atlasGraph;

        LOG.debug("==> AtlasTypeDefGraphStoreV1()");

        try {
            init();
            // commit/close the transaction after successful type store initialization.
            atlasGraph.commit();

        } catch (AtlasBaseException excp) {
            atlasGraph.rollback();
            LOG.error("failed to initialize types from graph store", excp);
        }

        LOG.debug("<== AtlasTypeDefGraphStoreV1()");
    }

    @Override
    protected AtlasEnumDefStore getEnumDefStore(AtlasTypeRegistry typeRegistry) {
        return new AtlasEnumDefStoreV1(this, typeRegistry);
    }

    @Override
    protected AtlasStructDefStore getStructDefStore(AtlasTypeRegistry typeRegistry) {
        return new AtlasStructDefStoreV1(this, typeRegistry);
    }

    @Override
    protected AtlasClassificationDefStore getClassificationDefStore(AtlasTypeRegistry typeRegistry) {
        return new AtlasClassificationDefStoreV1(this, typeRegistry);
    }

    @Override
    protected AtlasEntityDefStore getEntityDefStore(AtlasTypeRegistry typeRegistry) {
        return new AtlasEntityDefStoreV1(this, typeRegistry);
    }

    @Override
    protected AtlasRelationshipDefStore getRelationshipDefStore(AtlasTypeRegistry typeRegistry) {
        return new AtlasRelationshipDefStoreV1(this, typeRegistry);
    }


    @Override
    @PostConstruct
    public void init() throws AtlasBaseException {
        LOG.debug("==> AtlasTypeDefGraphStoreV1.init()");

        super.init();

        LOG.debug("<== AtlasTypeDefGraphStoreV1.init()");
    }

    AtlasGraph getAtlasGraph() { return atlasGraph; }

    @VisibleForTesting
    public AtlasVertex findTypeVertexByName(String typeName) {
        Iterator results = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
                .has(Constants.TYPENAME_PROPERTY_KEY, typeName)
                .vertices().iterator();

        return (results != null && results.hasNext()) ? (AtlasVertex) results.next() : null;
    }

    AtlasVertex findTypeVertexByNameAndCategory(String typeName, TypeCategory category) {
        Iterator results = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
                .has(Constants.TYPENAME_PROPERTY_KEY, typeName)
                .has(TYPE_CATEGORY_PROPERTY_KEY, category)
                .vertices().iterator();

        return (results != null && results.hasNext()) ? (AtlasVertex) results.next() : null;
    }

    AtlasVertex findTypeVertexByGuid(String typeGuid) {
        Iterator<AtlasVertex> vertices = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
                .has(Constants.GUID_PROPERTY_KEY, typeGuid)
                .vertices().iterator();

        return (vertices != null && vertices.hasNext()) ? vertices.next() : null;
    }

    AtlasVertex findTypeVertexByGuidAndCategory(String typeGuid, TypeCategory category) {
        Iterator<AtlasVertex> vertices = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
                .has(Constants.GUID_PROPERTY_KEY, typeGuid)
                .has(TYPE_CATEGORY_PROPERTY_KEY, category)
                .vertices().iterator();

        return (vertices != null && vertices.hasNext()) ? vertices.next() : null;
    }

    Iterator<AtlasVertex> findTypeVerticesByCategory(TypeCategory category) {

        return (Iterator<AtlasVertex>) atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
                .has(TYPE_CATEGORY_PROPERTY_KEY, category)
                .vertices().iterator();
    }

    AtlasVertex createTypeVertex(AtlasBaseTypeDef typeDef) {
        // Validate all the required checks
        Preconditions.checkArgument(StringUtils.isNotBlank(typeDef.getName()), "Type name can't be null/empty");

        AtlasVertex ret = atlasGraph.addVertex();

        if (StringUtils.isBlank(typeDef.getTypeVersion())) {
            typeDef.setTypeVersion("1.0");
        }

        if (typeDef.getVersion() == null) {
            typeDef.setVersion(1L);
        }

        if (StringUtils.isBlank(typeDef.getGuid())) {
            typeDef.setGuid(UUID.randomUUID().toString());
        }

        if (typeDef.getCreateTime() == null) {
            typeDef.setCreateTime(new Date());
        }

        if (typeDef.getUpdateTime() == null) {
            typeDef.setUpdateTime(new Date());
        }

        ret.setProperty(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE); // Mark as type vertex
        ret.setProperty(TYPE_CATEGORY_PROPERTY_KEY, getTypeCategory(typeDef));

        ret.setProperty(Constants.TYPENAME_PROPERTY_KEY, typeDef.getName());
        ret.setProperty(Constants.TYPEDESCRIPTION_PROPERTY_KEY,
                StringUtils.isNotBlank(typeDef.getDescription()) ? typeDef.getDescription() : typeDef.getName());
        ret.setProperty(Constants.TYPEVERSION_PROPERTY_KEY, typeDef.getTypeVersion());
        ret.setProperty(Constants.GUID_PROPERTY_KEY, typeDef.getGuid());
        ret.setProperty(Constants.TIMESTAMP_PROPERTY_KEY, typeDef.getCreateTime().getTime());
        ret.setProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, typeDef.getUpdateTime().getTime());
        ret.setProperty(Constants.VERSION_PROPERTY_KEY, typeDef.getVersion());
        ret.setProperty(Constants.TYPEOPTIONS_PROPERTY_KEY, AtlasType.toJson(typeDef.getOptions()));

        return ret;
    }

    void updateTypeVertex(AtlasBaseTypeDef typeDef, AtlasVertex vertex) {
        if (!isTypeVertex(vertex)) {
            LOG.warn("updateTypeVertex(): not a type-vertex - {}", vertex);

            return;
        }

        updateVertexProperty(vertex, Constants.GUID_PROPERTY_KEY, typeDef.getGuid());
        /*
         * rename of a type is supported yet - as the typename is used to in the name of the edges from this vertex
         * To support rename of types, he edge names should be derived from an internal-name - not directly the typename
         *
        updateVertexProperty(vertex, Constants.TYPENAME_PROPERTY_KEY, typeDef.getName());
         */
        updateVertexProperty(vertex, Constants.TYPEDESCRIPTION_PROPERTY_KEY, typeDef.getDescription());
        updateVertexProperty(vertex, Constants.TYPEVERSION_PROPERTY_KEY, typeDef.getTypeVersion());
        updateVertexProperty(vertex, Constants.TYPEOPTIONS_PROPERTY_KEY, AtlasType.toJson(typeDef.getOptions()));

        markVertexUpdated(vertex);
    }

    void deleteTypeVertexOutEdges(AtlasVertex vertex) throws AtlasBaseException {
        Iterable<AtlasEdge> edges = vertex.getEdges(AtlasEdgeDirection.OUT);

        for (AtlasEdge edge : edges) {
            atlasGraph.removeEdge(edge);
        }
    }

    /**
     * Look to see if there are any IN edges with the supplied label
     * @param vertex
     * @param label
     * @return
     * @throws AtlasBaseException
     */
    boolean hasIncomingEdgesWithLabel(AtlasVertex vertex, String label) throws AtlasBaseException {
        boolean foundEdges = false;
        Iterator<AtlasEdge> inEdges = vertex.getEdges(AtlasEdgeDirection.IN).iterator();

        while (inEdges.hasNext()) {
            AtlasEdge edge = inEdges.next();

            if (label.equals(edge.getLabel())) {
                foundEdges = true;
                break;
            }
        }
        return foundEdges;
    }

    void deleteTypeVertex(AtlasVertex vertex) throws AtlasBaseException {
        Iterator<AtlasEdge> inEdges = vertex.getEdges(AtlasEdgeDirection.IN).iterator();

        if (inEdges.hasNext()) {
            throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_REFERENCES);
        }

        Iterable<AtlasEdge> edges = vertex.getEdges(AtlasEdgeDirection.OUT);

        for (AtlasEdge edge : edges) {
            atlasGraph.removeEdge(edge);
        }
        atlasGraph.removeVertex(vertex);
    }

    void vertexToTypeDef(AtlasVertex vertex, AtlasBaseTypeDef typeDef) {
        String name        = vertex.getProperty(Constants.TYPENAME_PROPERTY_KEY, String.class);
        String description = vertex.getProperty(Constants.TYPEDESCRIPTION_PROPERTY_KEY, String.class);
        String typeVersion = vertex.getProperty(Constants.TYPEVERSION_PROPERTY_KEY, String.class);
        String guid        = vertex.getProperty(Constants.GUID_PROPERTY_KEY, String.class);
        Long   createTime  = vertex.getProperty(Constants.TIMESTAMP_PROPERTY_KEY, Long.class);
        Long   updateTime  = vertex.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, Long.class);
        Long   version     = vertex.getProperty(Constants.VERSION_PROPERTY_KEY, Long.class);
        String options     = vertex.getProperty(Constants.TYPEOPTIONS_PROPERTY_KEY, String.class);

        typeDef.setName(name);
        typeDef.setDescription(description);
        typeDef.setTypeVersion(typeVersion);
        typeDef.setGuid(guid);

        if (createTime != null) {
            typeDef.setCreateTime(new Date(createTime));
        }

        if (updateTime != null) {
            typeDef.setUpdateTime(new Date(updateTime));
        }

        if (version != null) {
            typeDef.setVersion(version);
        }

        if (options != null) {
            typeDef.setOptions(AtlasType.fromJson(options, Map.class));
        }
    }

    boolean isTypeVertex(AtlasVertex vertex) {
        String vertexType = vertex.getProperty(Constants.VERTEX_TYPE_PROPERTY_KEY, String.class);

        return VERTEX_TYPE.equals(vertexType);
    }

    @VisibleForTesting
    public boolean isTypeVertex(AtlasVertex vertex, TypeCategory category) {
        boolean ret = false;

        if (isTypeVertex(vertex)) {
            TypeCategory vertexCategory = vertex.getProperty(Constants.TYPE_CATEGORY_PROPERTY_KEY, TypeCategory.class);

            ret = category.equals(vertexCategory);
        }

        return ret;
    }

    boolean isTypeVertex(AtlasVertex vertex, TypeCategory[] categories) {
        boolean ret = false;

        if (isTypeVertex(vertex)) {
            TypeCategory vertexCategory = vertex.getProperty(TYPE_CATEGORY_PROPERTY_KEY, TypeCategory.class);

            for (TypeCategory category : categories) {
                if (category.equals(vertexCategory)) {
                    ret = true;

                    break;
                }
            }
        }

        return ret;
    }

    AtlasEdge getOrCreateEdge(AtlasVertex outVertex, AtlasVertex inVertex, String edgeLabel) {
        AtlasEdge           ret   = null;
        Iterable<AtlasEdge> edges = outVertex.getEdges(AtlasEdgeDirection.OUT, edgeLabel);

        for (AtlasEdge edge : edges) {
            if (edge.getInVertex().getId().equals(inVertex.getId())) {
                ret = edge;
                break;
            }
        }

        if (ret == null) {
            ret = addEdge(outVertex, inVertex, edgeLabel);
        }

        return ret;
    }

    AtlasEdge addEdge(AtlasVertex outVertex, AtlasVertex inVertex, String edgeLabel) {

        return atlasGraph.addEdge(outVertex, inVertex, edgeLabel);
    }

    void createSuperTypeEdges(AtlasVertex vertex, Set<String> superTypes, TypeCategory typeCategory)
            throws AtlasBaseException {
        Set<String> currentSuperTypes = getSuperTypeNames(vertex);

        if (CollectionUtils.isNotEmpty(superTypes)) {
            if (! superTypes.containsAll(currentSuperTypes)) {
                throw new AtlasBaseException(AtlasErrorCode.SUPERTYPE_REMOVAL_NOT_SUPPORTED);
            }

            for (String superType : superTypes) {
                AtlasVertex superTypeVertex = findTypeVertexByNameAndCategory(superType, typeCategory);

                getOrCreateEdge(vertex, superTypeVertex, AtlasGraphUtilsV1.SUPERTYPE_EDGE_LABEL);
            }
        } else if (CollectionUtils.isNotEmpty(currentSuperTypes)) {
            throw new AtlasBaseException(AtlasErrorCode.SUPERTYPE_REMOVAL_NOT_SUPPORTED);
        }
    }

    Set<String> getSuperTypeNames(AtlasVertex vertex) {
        Set<String>    ret   = new HashSet<>();
        Iterable<AtlasEdge> edges = vertex.getEdges(AtlasEdgeDirection.OUT, AtlasGraphUtilsV1.SUPERTYPE_EDGE_LABEL);

        for (AtlasEdge edge : edges) {
            ret.add(edge.getInVertex().getProperty(Constants.TYPENAME_PROPERTY_KEY, String.class));
        }

        return ret;
    }

    TypeCategory getTypeCategory(AtlasBaseTypeDef typeDef) {
        switch (typeDef.getCategory()) {
            case ENTITY:
                return TypeCategory.CLASS;

            case CLASSIFICATION:
                return TypeCategory.TRAIT;

            case STRUCT:
                return TypeCategory.STRUCT;

            case ENUM:
                return TypeCategory.ENUM;

            case RELATIONSHIP:
                return TypeCategory.RELATIONSHIP;
        }

        return null;
    }

    /*
     * update the given vertex property, if the new value is not-blank
     */
    private void updateVertexProperty(AtlasVertex vertex, String propertyName, String newValue) {
        if (StringUtils.isNotBlank(newValue)) {
            String currValue = vertex.getProperty(propertyName, String.class);

            if (!StringUtils.equals(currValue, newValue)) {
                vertex.setProperty(propertyName, newValue);
            }
        }
    }

    /*
     * update the given vertex property, if the new value is not-null
     */
    private void updateVertexProperty(AtlasVertex vertex, String propertyName, Date newValue) {
        if (newValue != null) {
            Number currValue = vertex.getProperty(propertyName, Number.class);

            if (currValue == null || !currValue.equals(newValue.getTime())) {
                vertex.setProperty(propertyName, newValue.getTime());
            }
        }
    }

    /*
     * increment the version value for this vertex
     */
    private void markVertexUpdated(AtlasVertex vertex) {
        Date   now         = new Date();
        Number currVersion = vertex.getProperty(Constants.VERSION_PROPERTY_KEY, Number.class);
        long   newVersion  = currVersion == null ? 1 : (currVersion.longValue() + 1);

        vertex.setProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, now.getTime());
        vertex.setProperty(Constants.VERSION_PROPERTY_KEY, newVersion);
    }
}
