package com.altamiracorp.lumify.web.routes.entity;

import com.altamiracorp.bigtable.model.Column;
import com.altamiracorp.bigtable.model.ColumnFamily;
import com.altamiracorp.bigtable.model.ModelSession;
import com.altamiracorp.lumify.core.model.audit.AuditAction;
import com.altamiracorp.lumify.core.model.audit.AuditRepository;
import com.altamiracorp.lumify.core.model.ontology.Concept;
import com.altamiracorp.lumify.core.model.ontology.LabelName;
import com.altamiracorp.lumify.core.model.ontology.OntologyRepository;
import com.altamiracorp.lumify.core.model.termMention.TermMentionModel;
import com.altamiracorp.lumify.core.model.termMention.TermMentionRepository;
import com.altamiracorp.lumify.core.model.termMention.TermMentionRowKey;
import com.altamiracorp.lumify.core.model.textHighlighting.TermMentionOffsetItem;
import com.altamiracorp.lumify.core.model.user.UserRepository;
import com.altamiracorp.lumify.core.user.User;
import com.altamiracorp.lumify.core.util.LumifyLogger;
import com.altamiracorp.lumify.core.util.LumifyLoggerFactory;
import com.altamiracorp.lumify.web.BaseRequestHandler;
import com.altamiracorp.miniweb.HandlerChain;
import com.altamiracorp.securegraph.*;
import com.altamiracorp.securegraph.util.IterableUtils;
import com.google.inject.Inject;
import org.json.JSONObject;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;
import java.util.List;

public class UnresolveTermEntity extends BaseRequestHandler {
    private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(UnresolveTermEntity.class);
    private final TermMentionRepository termMentionRepository;
    private final Graph graph;
    private final EntityHelper entityHelper;
    private final OntologyRepository ontologyRepository;
    private final AuditRepository auditRepository;
    private final UserRepository userRepository;
    private final ModelSession modelSession;

    @Inject
    public UnresolveTermEntity(
            final TermMentionRepository termMentionRepository,
            final Graph graph,
            final EntityHelper entityHelper,
            final OntologyRepository ontologyRepository,
            final AuditRepository auditRepository,
            final UserRepository userRepository,
            final ModelSession modelSession) {
        this.termMentionRepository = termMentionRepository;
        this.graph = graph;
        this.entityHelper = entityHelper;
        this.ontologyRepository = ontologyRepository;
        this.auditRepository = auditRepository;
        this.userRepository = userRepository;
        this.modelSession = modelSession;
    }

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, HandlerChain chain) throws Exception {
        // required parameters
        final String artifactId = getRequiredParameter(request, "artifactId");
        final long mentionStart = getRequiredParameterAsLong(request, "mentionStart");
        final long mentionEnd = getRequiredParameterAsLong(request, "mentionEnd");
        final String sign = getRequiredParameter(request, "sign");
        final String conceptId = getRequiredParameter(request, "conceptId");
        final String graphVertexId = getRequiredParameter(request, "graphVertexId");

        LOGGER.debug(
                "UnresolveTermEntity (artifactId: %s, mentionStart: %d, mentionEnd: %d, sign: %s, conceptId: %s, graphVertexId: %s)",
                artifactId,
                mentionStart,
                mentionEnd,
                sign,
                conceptId,
                graphVertexId);

        User user = getUser(request);
        Authorizations authorizations = userRepository.getAuthorizations(user);

        Vertex resolvedVertex = graph.getVertex(graphVertexId, authorizations);
        Vertex artifactVertex = graph.getVertex(artifactId, authorizations);

        // Unlinking the term with the vertex
        TermMentionRowKey termMentionRowKey = new TermMentionRowKey(artifactId, mentionStart, mentionEnd);
        TermMentionModel termMention = termMentionRepository.findByRowKey(termMentionRowKey.toString(), user.getModelUserContext());
        if (termMention == null) {
            termMention = new TermMentionModel(termMentionRowKey);
        }

        String columnFamilyName = termMention.getMetadata().getColumnFamilyName();
        String columnName = termMention.getMetadata().VERTEX_ID;
        termMention.get(columnFamilyName).getColumn(columnName).setDirty(true);
        modelSession.deleteColumn(termMention, termMention.getTableName(), columnFamilyName, columnName, user.getModelUserContext());
        termMention.getMetadata().setVertexId("");

        // If there is only instance of the term entity in this artifact delete the relationship
        Iterator<TermMentionModel> termMentionModels = termMentionRepository.findByGraphVertexId(artifactVertex.getId().toString(), user).iterator();
        boolean deleteEdge = false;
        Object edgeId = null;
        int termCount = 0;
        while (termMentionModels.hasNext()) {
            TermMentionModel termMentionModel = termMentionModels.next();
            Object termMentionId = termMentionModel.getMetadata().getGraphVertexId();
            if (termMentionId != null && termMentionId.equals(graphVertexId)) {
                termCount ++;
                break;
            }
        }
        if (termCount == 0) {
            Iterable<Edge> edges = artifactVertex.getEdges(resolvedVertex, Direction.OUT, LabelName.RAW_HAS_ENTITY.toString(), authorizations);
            Edge edge = edges.iterator().next();
            if (edge != null) {
                edgeId = edge.getId();
                graph.removeEdge(edge, authorizations);
                deleteEdge = true;
                graph.flush();
                auditRepository.auditRelationship(AuditAction.DELETE, artifactVertex, resolvedVertex, LabelName.RAW_HAS_ENTITY.toString(), "", "", user, new Visibility(""));
            }
        }

        entityHelper.scheduleHighlight(artifactId, user);

        TermMentionOffsetItem offsetItem = new TermMentionOffsetItem(termMention, null);
        JSONObject result = offsetItem.toJson();
        if (deleteEdge) {
            result.put("deleteEdge", deleteEdge);
            result.put("edgeId", edgeId);
        }
        respondWithJson(response, result);
    }
}

@@ -49,108 +49,8 @@
 y;%0A%0A
-import com.altamiracorp.bigtable.model.Column;%0Aimport com.altamiracorp.bigtable.model.ColumnFamily;%0A
 impo
@@ -228,68 +228,8 @@
 ry;%0A
-import com.altamiracorp.lumify.core.model.ontology.Concept;%0A
 impo
@@ -1032,64 +1032,8 @@
 .*;%0A
-import com.altamiracorp.securegraph.util.IterableUtils;%0A
 impo
@@ -1213,31 +1213,8 @@
 tor;
-%0Aimport java.util.List;
 %0A%0Apu

optimize imports