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

import com.altamiracorp.lumify.core.model.audit.AuditAction;
import com.altamiracorp.lumify.core.model.audit.AuditRepository;
import com.altamiracorp.lumify.core.model.ontology.LabelName;
import com.altamiracorp.lumify.core.model.ontology.PropertyName;
import com.altamiracorp.lumify.core.user.User;
import com.altamiracorp.lumify.web.BaseRequestHandler;
import com.altamiracorp.miniweb.HandlerChain;
import com.altamiracorp.securegraph.Graph;
import com.google.inject.Inject;
import org.json.JSONArray;
import org.json.JSONObject;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

public class EntityObjectDetectionDelete extends BaseRequestHandler {
    private final Graph graph;
    private final EntityHelper entityHelper;
    private final AuditRepository auditRepository;

    @Inject
    public EntityObjectDetectionDelete(
            final Graph graph,
            final EntityHelper entityHelper,
            final AuditRepository auditRepository) {
        this.graph = graph;
        this.entityHelper = entityHelper;
        this.auditRepository = auditRepository;
    }

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, HandlerChain chain) throws Exception {
        JSONObject jsonObject = new JSONObject(getRequiredParameter(request, "objectInfo"));
        User user = getUser(request);

        // Delete just the relationship if vertex has more than one relationship otherwise delete vertex
        String graphVertexId = jsonObject.getString("graphVertexId");
        JSONObject obj = new JSONObject();
        obj.put("entityVertex", graph.findVertex(graphVertexId, user).toJson());
        Map<GraphRelationship, GraphVertex> relationships = graph.getRelationships(graphVertexId, user);
        GraphVertex artifactVertex = graph.findVertex(jsonObject.getString("artifactId"), user);
        if (relationships.size() > 1) {
            String edgeId = artifactVertex.getId() + ">" + graphVertexId + "|" + LabelName.CONTAINS_IMAGE_OF.toString();
            obj.put("edgeId", edgeId);
            graph.removeRelationship(artifactVertex.getId(), graphVertexId, LabelName.CONTAINS_IMAGE_OF.toString(), user);
        } else {
            // TODO: replace "" when we implement commenting on ui
            auditRepository.auditEntity(AuditAction.DELETE.toString(), graphVertexId, artifactVertex.getId(), jsonObject.getString("title"),
                    jsonObject.getString("_conceptType"), "", "", user);
            graph.remove(graphVertexId, user);
            obj.put("remove", true);
        }

        // Delete the appropriate detected object json object from the array and reset the property
        JSONArray detectedObjects = new JSONArray(artifactVertex.getProperty(PropertyName.DETECTED_OBJECTS).toString());
        boolean deleted = false;
        for (int i = 0; i < detectedObjects.length(); i++) {
            JSONObject detectedObject = detectedObjects.getJSONObject(i);
            if (detectedObject.has("graphVertexId") && detectedObject.get("graphVertexId").equals(jsonObject.get("graphVertexId"))) {
                detectedObjects.remove(i);
                deleted = true;
                break;
            }
        }
        if (!deleted) {
            throw new RuntimeException("Tag was not found in the list of detected objects");
        }
        artifactVertex.setProperty(PropertyName.DETECTED_OBJECTS, detectedObjects.toString());
        graph.save(artifactVertex, user);

        // TODO: replace "" when we implement commenting on ui
        auditRepository.auditEntityProperties(AuditAction.UPDATE.toString(), artifactVertex, PropertyName.DETECTED_OBJECTS.toString(), "", "", user);

        JSONObject updatedArtifactVertex = entityHelper.formatUpdatedArtifactVertexProperty(artifactVertex.getId(), PropertyName.DETECTED_OBJECTS.toString(), artifactVertex.getProperty(PropertyName.DETECTED_OBJECTS));
        obj.put("updatedArtifactVertex", updatedArtifactVertex);

        //TODO: Overwrite old ElasticSearch index with new info

        respondWithJson(response, obj);
    }
}

@@ -341,24 +341,76 @@
 .user.User;%0A
+import com.altamiracorp.lumify.core.util.GraphUtil;%0A
 import com.a
@@ -534,21 +534,17 @@
 regraph.
-Graph
+*
 ;%0Aimport
@@ -722,30 +722,8 @@
 nse;
-%0Aimport java.util.Map;
 %0A%0Apu
@@ -1358,16 +1358,99 @@
 ption %7B%0A
+        // TODO set visibility%0A        Visibility visibility = new Visibility(%22%22);%0A
         
@@ -1803,42 +1803,33 @@
     
-obj.put(%22entityV
+Vertex v
 ertex
-%22,
+ =
  graph.
-find
+get
 Vert
@@ -1854,16 +1854,26 @@
 user
-).toJs
+.getAuthorizati
 on
+s
 ());
@@ -1885,113 +1885,68 @@
     
-Map%3CGraphRelationship, GraphVertex%3E relationships = graph.getRelationships(graphVertexId, user
+obj.put(%22entityVertex%22, GraphUtil.toJson(vertex)
 );%0A
+%0A
         
 Grap
@@ -1941,21 +1941,16 @@
         
-Graph
 Vertex a
@@ -1975,12 +1975,11 @@
 aph.
-find
+get
 Vert
@@ -2025,47 +2025,215 @@
 user
-);%0A        if (relationships.size() %3E 1
+.getAuthorizations());%0A        Iterable%3CEdge%3E edges = artifactVertex.getEdges(vertex, Direction.BOTH, LabelName.CONTAINS_IMAGE_OF.toString(), user.getAuthorizations());%0A        if (edges.iterator().hasNext()
 ) %7B%0A
@@ -2408,118 +2408,143 @@
     
-graph.removeRelationship(artifactVertex.getId(), graphVertexId, LabelName.CONTAINS_IMAGE_OF.toString(), user);
+while (edges.iterator().hasNext()) %7B%0A                graph.removeEdge(edges.iterator().next(), user.getAuthorizations());%0A            %7D
 %0A   
@@ -2732,16 +2732,27 @@
 .getId()
+.toString()
 , jsonOb
@@ -2873,16 +2873,22 @@
 h.remove
+Vertex
 (graphVe
@@ -2895,24 +2895,44 @@
 rtexId, user
+.getAuthorizations()
 );%0A         
@@ -3138,32 +3138,37 @@
 rtex.getProperty
+Value
 (PropertyName.DE
@@ -3181,16 +3181,30 @@
 _OBJECTS
+.toString(), 0
 ).toStri
@@ -3825,16 +3825,27 @@
 _OBJECTS
+.toString()
 , detect
@@ -3868,50 +3868,20 @@
 ng()
-);%0A        graph.save(artifactVertex, user
+, visibility
 );%0A%0A
@@ -4208,16 +4208,27 @@
 .getId()
+.toString()
 , Proper
@@ -4281,32 +4281,37 @@
 rtex.getProperty
+Value
 (PropertyName.DE
@@ -4324,16 +4324,30 @@
 _OBJECTS
+.toString(), 0
 ));%0A    

fix object detection delete