/**
 * 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
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * 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.catalog;

import org.apache.atlas.catalog.definition.EntityTagResourceDefinition;
import org.apache.atlas.catalog.exception.*;
import org.apache.atlas.catalog.query.AtlasQuery;

import java.util.*;

/**
 * Provider for entity tag resources.
 */
public class EntityTagResourceProvider extends BaseResourceProvider implements ResourceProvider {
    private TermResourceProvider termResourceProvider;

    public EntityTagResourceProvider(AtlasTypeSystem typeSystem) {
        super(typeSystem, new EntityTagResourceDefinition());
    }

    @Override
    public Result getResourceById(Request request) throws ResourceNotFoundException {
        AtlasQuery atlasQuery;
        try {
            atlasQuery = queryFactory.createEntityTagQuery(request);
        } catch (InvalidQueryException e) {
            throw new CatalogRuntimeException("Unable to compile internal Entity Tag query: " + e, e);
        }
        Collection<Map<String, Object>> results = atlasQuery.execute();
        if (results.isEmpty()) {
            throw new ResourceNotFoundException(String.format("Tag '%s' not found.",
                    request.getProperty(resourceDefinition.getIdPropertyName())));
        }

        return new Result(results);
    }

    @Override
    public Result getResources(Request request) throws InvalidQueryException, ResourceNotFoundException {
        AtlasQuery atlasQuery = queryFactory.createEntityTagQuery(request);
        return new Result(atlasQuery.execute());
    }

    @Override
    public void createResource(Request request)
            throws InvalidPayloadException, ResourceAlreadyExistsException, ResourceNotFoundException {

        String entityId = String.valueOf(request.getQueryProperties().remove("id"));
        resourceDefinition.validateCreatePayload(request);
        Result termResult = getTermQueryResult(request.<String>getProperty("name"));
        Map<String, Object> termProperties = termResult.getPropertyMaps().iterator().next();
        //todo: use constant for property name
        if (String.valueOf(termProperties.get("available_as_tag")).equals("false")) {
            throw new InvalidPayloadException(
                    "Attempted to tag an entity with a term which is not available to be tagged");
        }
        tagEntities(Collections.singleton(entityId), termProperties);
    }

    //todo: response for case mixed case where some subset of creations fail
    @Override
    public Collection<String> createResources(Request request)
            throws InvalidQueryException, ResourceNotFoundException, ResourceAlreadyExistsException {

        Collection<String> relativeUrls = new ArrayList<>();
        AtlasQuery atlasQuery = queryFactory.createEntityQuery(request);
        Collection<String> guids = new ArrayList<>();
        for (Map<String, Object> entityMap: atlasQuery.execute()) {
            guids.add(String.valueOf(entityMap.get("id")));
        }

        Collection<Map<String, String>> tagMaps = request.getProperty("tags");
        for (Map<String, String> tagMap : tagMaps) {
            Result termResult = getTermQueryResult(tagMap.get("name"));
            relativeUrls.addAll(tagEntities(guids, termResult.getPropertyMaps().iterator().next()));
        }
        return relativeUrls;
    }

    @Override
    public void deleteResourceById(Request request) throws ResourceNotFoundException, InvalidPayloadException {
        typeSystem.deleteTag(request.<String>getProperty("id"), request.<String>getProperty("name"));
    }

    private Result getTermQueryResult(String termName) throws ResourceNotFoundException {
        Request tagRequest = new InstanceRequest(
                Collections.<String, Object>singletonMap("termPath", new TermPath(termName)));

        tagRequest.addAdditionalSelectProperties(Collections.singleton("type"));
        return getTermResourceProvider().getResourceById(tagRequest);
    }

    private Collection<String> tagEntities(Collection<String> entityGuids, Map<String, Object> termProperties)
            throws ResourceAlreadyExistsException {

        Collection<String> relativeUrls = new ArrayList<>();
        for (String guid : entityGuids) {
            //createTermEdge(entity, Collections.singleton(termVertex));
            // copy term properties from trait associated with taxonomy to be set
            // on trait associated with new entity (basically clone at time of tag event)
            //todo: any changes to 'singleton' trait won't be reflected in new trait
            //todo: iterate over properties in term definition instead of hard coding here
            Map<String, Object> properties = new HashMap<>();
            String termName = String.valueOf(termProperties.get("name"));
            properties.put("name", termName);
            properties.put("description", termProperties.get("description"));

            typeSystem.createTraitInstance(guid, termName, properties);
            //todo: *** shouldn't know anything about href structure in this class ***
            relativeUrls.add(String.format("v1/entities/%s/tags/%s", guid, termName));
        }
        return relativeUrls;
    }

    protected synchronized ResourceProvider getTermResourceProvider() {
        if (termResourceProvider == null) {
            termResourceProvider = new TermResourceProvider(typeSystem);
        }
        return termResourceProvider;
    }
}
