/**
 * 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.notification.entity;

import org.apache.atlas.AtlasException;
import org.apache.atlas.typesystem.IReferenceableInstance;
import org.apache.atlas.typesystem.IStruct;
import org.apache.atlas.typesystem.Referenceable;
import org.apache.atlas.typesystem.Struct;
import org.apache.atlas.typesystem.types.FieldMapping;
import org.apache.atlas.typesystem.types.TraitType;
import org.apache.atlas.typesystem.types.TypeSystem;

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * Entity notification implementation.
 */
public class EntityNotificationImpl implements EntityNotification {

    private final Referenceable entity;
    private final OperationType operationType;
    private final List<IStruct> traits;


    // ----- Constructors ------------------------------------------------------

    /**
     * No-arg constructor for serialization.
     */
    @SuppressWarnings("unused")
    private EntityNotificationImpl() throws AtlasException {
        this(null, OperationType.ENTITY_CREATE, Collections.<IStruct>emptyList());
    }

    /**
     * Construct an EntityNotification.
     *
     * @param entity            the entity subject of the notification
     * @param operationType     the type of operation that caused the notification
     * @param traits            the traits for the given entity
     *
     * @throws AtlasException if the entity notification can not be created
     */
    public EntityNotificationImpl(Referenceable entity, OperationType operationType, List<IStruct> traits)
        throws AtlasException {
        this.entity = entity;
        this.operationType = operationType;
        this.traits = traits;
    }

    /**
     * Construct an EntityNotification.
     *
     * @param entity         the entity subject of the notification
     * @param operationType  the type of operation that caused the notification
     * @param typeSystem     the Atlas type system
     *
     * @throws AtlasException if the entity notification can not be created
     */
    public EntityNotificationImpl(Referenceable entity, OperationType operationType, TypeSystem typeSystem)
        throws AtlasException {
        this(entity, operationType, getAllTraits(entity, typeSystem));
    }


    // ----- EntityNotification ------------------------------------------------

    @Override
    public IReferenceableInstance getEntity() {
        return entity;
    }

    @Override
    public List<IStruct> getAllTraits() {
        return traits;
    }

    @Override
    public OperationType getOperationType() {
        return operationType;
    }


    // ----- Object overrides --------------------------------------------------

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        EntityNotificationImpl that = (EntityNotificationImpl) o;
        return Objects.equals(entity, that.entity) &&
                operationType == that.operationType &&
                Objects.equals(traits, that.traits);
    }

    @Override
    public int hashCode() {
        return Objects.hash(entity, operationType, traits);
    }


    // ----- helper methods ----------------------------------------------------

    private static List<IStruct> getAllTraits(IReferenceableInstance entityDefinition,
                                              TypeSystem typeSystem) throws AtlasException {
        List<IStruct> traitInfo = new LinkedList<>();
        for (String traitName : entityDefinition.getTraits()) {
            IStruct trait = entityDefinition.getTrait(traitName);
            String typeName = trait.getTypeName();
            Map<String, Object> valuesMap = trait.getValuesMap();
            traitInfo.add(new Struct(typeName, valuesMap));
            traitInfo.addAll(getSuperTraits(typeName, valuesMap, typeSystem));
        }
        return traitInfo;
    }

    private static List<IStruct> getSuperTraits(
            String typeName, Map<String, Object> values, TypeSystem typeSystem) throws AtlasException {

        List<IStruct> superTypes = new LinkedList<>();

        TraitType traitDef = typeSystem.getDataType(TraitType.class, typeName);
        Set<String> superTypeNames = traitDef.getAllSuperTypeNames();

        for (String superTypeName : superTypeNames) {
            TraitType superTraitDef = typeSystem.getDataType(TraitType.class, superTypeName);

            Map<String, Object> superTypeValues = new HashMap<>();

            FieldMapping fieldMapping = superTraitDef.fieldMapping();

            if (fieldMapping != null) {
                Set<String> superTypeAttributeNames = fieldMapping.fields.keySet();

                for (String superTypeAttributeName : superTypeAttributeNames) {
                    if (values.containsKey(superTypeAttributeName)) {
                        superTypeValues.put(superTypeAttributeName, values.get(superTypeAttributeName));
                    }
                }
            }
            IStruct superTrait = new Struct(superTypeName, superTypeValues);
            superTypes.add(superTrait);
            superTypes.addAll(getSuperTraits(superTypeName, values, typeSystem));
        }

        return superTypes;
    }
}
