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

import com.google.common.collect.ImmutableSet;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.typedef.*;
import org.apache.atlas.model.typedef.AtlasEnumDef.AtlasEnumElementDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.*;

/**
 * Utility methods for AtlasType/AtlasTypeDef.
 */
public class AtlasTypeUtil {
    private static final Set<String> ATLAS_BUILTIN_TYPENAMES = new HashSet<>();
    private static final String  NAME_REGEX         = "[a-zA-Z][a-zA-Z0-9_ ]*";
    private static final String  TRAIT_NAME_REGEX   = "[a-zA-Z][a-zA-Z0-9_ .]*";
    private static final Pattern NAME_PATTERN       = Pattern.compile(NAME_REGEX);
    private static final Pattern TRAIT_NAME_PATTERN = Pattern.compile(TRAIT_NAME_REGEX);

    private static final String InvalidTypeNameErrorMessage      = "Name must consist of a letter followed by a sequence of [ letter, number, '_' ] characters.";
    private static final String InvalidTraitTypeNameErrorMessage = "Name must consist of a letter followed by a sequence of [ letter,  number, '_', '.' ] characters.";

    static {
        Collections.addAll(ATLAS_BUILTIN_TYPENAMES, AtlasBaseTypeDef.ATLAS_BUILTIN_TYPES);
    }

    public static Set<String> getReferencedTypeNames(String typeName) {
        Set<String> ret = new HashSet<>();

        getReferencedTypeNames(typeName, ret);

        return ret;
    }

    public static boolean isBuiltInType(String typeName) {
        return ATLAS_BUILTIN_TYPENAMES.contains(typeName);
    }

    public static boolean isArrayType(String typeName) {
        return StringUtils.startsWith(typeName, ATLAS_TYPE_ARRAY_PREFIX)
            && StringUtils.endsWith(typeName, ATLAS_TYPE_ARRAY_SUFFIX);
    }

    public static boolean isMapType(String typeName) {
        return StringUtils.startsWith(typeName, ATLAS_TYPE_MAP_PREFIX)
            && StringUtils.endsWith(typeName, ATLAS_TYPE_MAP_SUFFIX);
    }

    public static boolean isValidTypeName(String typeName) {
        Matcher m = NAME_PATTERN.matcher(typeName);

        return m.matches();
    }

    public static String getInvalidTypeNameErrorMessage() {
        return InvalidTypeNameErrorMessage;
    }

    public static boolean isValidTraitTypeName(String typeName) {
        Matcher m = TRAIT_NAME_PATTERN.matcher(typeName);

        return m.matches();
    }

    public static String getInvalidTraitTypeNameErrorMessage() {
        return InvalidTraitTypeNameErrorMessage;
    }

    public static String getStringValue(Map map, Object key) {
        Object ret = map != null ? map.get(key) : null;

        return ret != null ? ret.toString() : null;
    }

    private static void getReferencedTypeNames(String typeName, Set<String> referencedTypeNames) {
        if (StringUtils.isNotBlank(typeName) && !referencedTypeNames.contains(typeName)) {
            if (typeName.startsWith(ATLAS_TYPE_ARRAY_PREFIX) && typeName.endsWith(ATLAS_TYPE_ARRAY_SUFFIX)) {
                int    startIdx        = ATLAS_TYPE_ARRAY_PREFIX.length();
                int    endIdx          = typeName.length() - ATLAS_TYPE_ARRAY_SUFFIX.length();
                String elementTypeName = typeName.substring(startIdx, endIdx);

                getReferencedTypeNames(elementTypeName, referencedTypeNames);
            } else if (typeName.startsWith(ATLAS_TYPE_MAP_PREFIX) && typeName.endsWith(ATLAS_TYPE_MAP_SUFFIX)) {
                int      startIdx      = ATLAS_TYPE_MAP_PREFIX.length();
                int      endIdx        = typeName.length() - ATLAS_TYPE_MAP_SUFFIX.length();
                String[] keyValueTypes = typeName.substring(startIdx, endIdx).split(ATLAS_TYPE_MAP_KEY_VAL_SEP, 2);
                String   keyTypeName   = keyValueTypes.length > 0 ? keyValueTypes[0] : null;
                String   valueTypeName = keyValueTypes.length > 1 ? keyValueTypes[1] : null;

                getReferencedTypeNames(keyTypeName, referencedTypeNames);
                getReferencedTypeNames(valueTypeName, referencedTypeNames);
            } else {
                referencedTypeNames.add(typeName);
            }
        }

    }

    public static AtlasAttributeDef createOptionalAttrDef(String name, AtlasType dataType) {
        return new AtlasAttributeDef(name, dataType.getTypeName(), true,
            Cardinality.SINGLE, 0, 1,
            false, false,
            Collections.<AtlasConstraintDef>emptyList());
    }

    public static AtlasAttributeDef createOptionalAttrDef(String name, String dataType) {
        return new AtlasAttributeDef(name, dataType, true,
            Cardinality.SINGLE, 0, 1,
            false, false,
            Collections.<AtlasConstraintDef>emptyList());
    }

    public static AtlasAttributeDef createRequiredAttrDef(String name, String dataType) {
        return new AtlasAttributeDef(name, dataType, false,
            Cardinality.SINGLE, 1, 1,
            false, true,
            Collections.<AtlasConstraintDef>emptyList());
    }

    public static AtlasAttributeDef createListRequiredAttrDef(String name, String dataType) {
        return new AtlasAttributeDef(name, dataType, false,
                Cardinality.LIST, 1, Integer.MAX_VALUE,
                false, true,
                Collections.<AtlasConstraintDef>emptyList());
    }

    public static AtlasAttributeDef createOptionalListAttrDef(String name, String dataType) {
        return new AtlasAttributeDef(name, dataType, true,
                Cardinality.LIST, 1, Integer.MAX_VALUE,
                false, true,
                Collections.<AtlasConstraintDef>emptyList());
    }

    public static AtlasAttributeDef createRequiredListAttrDefWithConstraint(String name, String dataType, String type, Map param) {
        AtlasAttributeDef ret = AtlasTypeUtil.createListRequiredAttrDef(name, dataType);
        ret.addConstraint(new AtlasConstraintDef(type, param));

        return ret;
    }

    public static AtlasAttributeDef createRequiredAttrDefWithConstraint(String name, String typeName, String type, Map param) {
        AtlasAttributeDef ret = AtlasTypeUtil.createRequiredAttrDef(name, typeName);
        ret.addConstraint(new AtlasConstraintDef(type, param));

        return ret;
    }

    public static AtlasAttributeDef createOptionalAttrDefWithConstraint(String name, String typeName, String type, Map param) {
        AtlasAttributeDef ret = AtlasTypeUtil.createOptionalAttrDef(name, typeName);
        ret.addConstraint(new AtlasConstraintDef(type, param));

        return ret;
    }

    public static AtlasAttributeDef createUniqueRequiredAttrDef(String name, AtlasType dataType) {
        return new AtlasAttributeDef(name, dataType.getTypeName(), false,
            Cardinality.SINGLE, 1, 1,
            true, true,
            Collections.<AtlasConstraintDef>emptyList());
    }

    public static AtlasAttributeDef createUniqueRequiredAttrDef(String name, String typeName) {
        return new AtlasAttributeDef(name, typeName, false,
            Cardinality.SINGLE, 1, 1,
            true, true,
            Collections.<AtlasConstraintDef>emptyList());
    }

    public static AtlasAttributeDef createRequiredAttrDef(String name, AtlasType dataType) {
        return new AtlasAttributeDef(name, dataType.getTypeName(), false,
            Cardinality.SINGLE, 1, 1,
            false, true,
            Collections.<AtlasConstraintDef>emptyList());
    }

    public static AtlasEnumDef createEnumTypeDef(String name, String description, AtlasEnumElementDef... enumValues) {
        return new AtlasEnumDef(name, description, "1.0", Arrays.asList(enumValues));
    }

    public static AtlasClassificationDef createTraitTypeDef(String name, ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
        return createTraitTypeDef(name, null, superTypes, attrDefs);
    }

    public static AtlasClassificationDef createTraitTypeDef(String name, String description, ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
        return createTraitTypeDef(name, description, "1.0", superTypes, attrDefs);
    }

    public static AtlasClassificationDef createTraitTypeDef(String name, String description, String version, ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
        return new AtlasClassificationDef(name, description, version, Arrays.asList(attrDefs), superTypes);
    }

    public static AtlasStructDef createStructTypeDef(String name, AtlasAttributeDef... attrDefs) {
        return createStructTypeDef(name, null, attrDefs);
    }

    public static AtlasStructDef createStructTypeDef(String name, String description, AtlasAttributeDef... attrDefs) {
        return new AtlasStructDef(name, description, "1.0", Arrays.asList(attrDefs));
    }

    public static AtlasEntityDef createClassTypeDef(String name,
        ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
        return createClassTypeDef(name, null, "1.0", superTypes, attrDefs);
    }

    public static AtlasEntityDef createClassTypeDef(String name, String description,
        ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
        return createClassTypeDef(name, description, "1.0", superTypes, attrDefs);
    }

    public static AtlasEntityDef createClassTypeDef(String name, String description, String version,
        ImmutableSet<String> superTypes, AtlasAttributeDef... attrDefs) {
        return new AtlasEntityDef(name, description, version, Arrays.asList(attrDefs), superTypes);
    }

    public static AtlasRelationshipDef createRelationshipTypeDef(String                  name,
                                                                 String                  description,
                                                                 String                  version,
                                                                 RelationshipCategory    relationshipCategory,
                                                                 PropagateTags           propagateTags,
                                                                 AtlasRelationshipEndDef endDef1,
                                                                 AtlasRelationshipEndDef endDef2,
                                                                 AtlasAttributeDef...    attrDefs) {
        return new AtlasRelationshipDef(name, description, version, relationshipCategory, propagateTags,
                                        endDef1, endDef2, Arrays.asList(attrDefs));
    }

    public static AtlasTypesDef getTypesDef(List<AtlasEnumDef> enums,
        List<AtlasStructDef> structs,
        List<AtlasClassificationDef> traits,
        List<AtlasEntityDef> classes) {
        return new AtlasTypesDef(enums, structs, traits, classes);
    }

    public static List<AtlasTypeDefHeader> toTypeDefHeader(AtlasTypesDef typesDef) {
        List<AtlasTypeDefHeader> headerList = new LinkedList<>();
        if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) {
            for (AtlasEnumDef enumDef : typesDef.getEnumDefs()) {
                headerList.add(new AtlasTypeDefHeader(enumDef));
            }
        }
        if (CollectionUtils.isNotEmpty(typesDef.getStructDefs())) {
            for (AtlasStructDef structDef : typesDef.getStructDefs()) {
                headerList.add(new AtlasTypeDefHeader(structDef));
            }
        }
        if (CollectionUtils.isNotEmpty(typesDef.getClassificationDefs())) {
            for (AtlasClassificationDef classificationDef : typesDef.getClassificationDefs()) {
                headerList.add(new AtlasTypeDefHeader(classificationDef));
            }
        }
        if (CollectionUtils.isNotEmpty(typesDef.getEntityDefs())) {
            for (AtlasEntityDef entityDef : typesDef.getEntityDefs()) {
                headerList.add(new AtlasTypeDefHeader(entityDef));
            }
        }
        if (CollectionUtils.isNotEmpty(typesDef.getRelationshipDefs())) {
            for (AtlasRelationshipDef relationshipDef : typesDef.getRelationshipDefs()) {
                headerList.add(new AtlasTypeDefHeader(relationshipDef));
            }
        }

        return headerList;
    }

    public static Collection<AtlasObjectId> toObjectIds(Collection<AtlasEntity> entities) {
        List<AtlasObjectId> ret = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(entities)) {
            for (AtlasEntity entity : entities) {
                if (entity != null) {
                    ret.add(AtlasTypeUtil.getAtlasObjectId(entity));
                }
            }
        }

        return ret;
    }

    public static Map toStructAttributes(Map map) {
        if (map != null && map.containsKey("typeName") && map.containsKey("attributes") && map.get("attributes") instanceof Map) {
            return (Map)map.get("attributes");
        }

        return map;
    }

    public static AtlasObjectId getAtlasObjectId(AtlasEntity entity) {
        return new AtlasObjectId(entity.getGuid(), entity.getTypeName());
    }

    public static AtlasObjectId getAtlasObjectId(AtlasEntityHeader header) {
        return new AtlasObjectId(header.getGuid(), header.getTypeName());
    }

    public static boolean isValidGuid(AtlasObjectId objId) {
        return isValidGuid(objId.getGuid());
    }

    public static boolean isAssignedGuid(AtlasObjectId objId) {
        return isAssignedGuid(objId.getGuid());
    }

    public static boolean isUnAssignedGuid(AtlasObjectId objId) {
        return isUnAssignedGuid(objId.getGuid());
    }

    public static boolean isValidGuid(String guid) {
        return isAssignedGuid(guid) || isUnAssignedGuid(guid);
    }

    public static boolean isAssignedGuid(String guid) {
        if (guid != null) {
            try {
                UUID.fromString(guid);
                return true;
            } catch (IllegalArgumentException e) {
                // ignore
            }
        }
        return false;
    }

    public static boolean isUnAssignedGuid(String guid) {
        return guid != null && guid.length() > 0 && guid.charAt(0) == '-';
    }

    public static boolean isValid(AtlasObjectId objId) {
        if (isAssignedGuid(objId) || isUnAssignedGuid(objId)) {
            return true;
        } else if (StringUtils.isNotEmpty(objId.getTypeName()) && MapUtils.isNotEmpty(objId.getUniqueAttributes())) {
            return true;
        }

        return false;
    }

    public static String toDebugString(AtlasTypesDef typesDef) {
        StringBuilder sb = new StringBuilder();

        sb.append("typesDef={");
        if (typesDef != null) {
            sb.append("enumDefs=[");
            dumpTypeNames(typesDef.getEnumDefs(), sb);
            sb.append("],");

            sb.append("structDefs=[");
            dumpTypeNames(typesDef.getStructDefs(), sb);
            sb.append("],");

            sb.append("classificationDefs=[");
            dumpTypeNames(typesDef.getClassificationDefs(), sb);
            sb.append("],");

            sb.append("entityDefs=[");
            dumpTypeNames(typesDef.getEntityDefs(), sb);
            sb.append("]");

            sb.append("relationshipDefs=[");
            dumpTypeNames(typesDef.getRelationshipDefs(), sb);
            sb.append("]");
        }
        sb.append("}");

        return sb.toString();
    }

    private static void dumpTypeNames(List<? extends AtlasBaseTypeDef> typeDefs, StringBuilder sb) {
        if (CollectionUtils.isNotEmpty(typeDefs)) {
            for (int i = 0; i < typeDefs.size(); i++) {
                AtlasBaseTypeDef typeDef = typeDefs.get(i);

                if (i > 0) {
                    sb.append(",");
                }

                sb.append(typeDef.getName());
            }
        }
    }
}