package io.lumify.web.routes.vertex;

import com.altamiracorp.miniweb.HandlerChain;
import com.google.inject.Inject;
import io.lumify.core.config.Configuration;
import io.lumify.core.exception.LumifyAccessDeniedException;
import io.lumify.core.exception.LumifyException;
import io.lumify.core.model.user.UserRepository;
import io.lumify.core.model.workspace.WorkspaceRepository;
import io.lumify.core.user.User;
import io.lumify.core.util.JsonSerializer;
import io.lumify.web.BaseRequestHandler;
import org.json.JSONArray;
import org.json.JSONObject;
import org.securegraph.Authorizations;
import org.securegraph.Graph;
import org.securegraph.Vertex;
import org.securegraph.util.ConvertingIterable;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static io.lumify.core.util.CollectionUtil.toIterable;

public class VertexMultiple extends BaseRequestHandler {
    private final Graph graph;

    @Inject
    public VertexMultiple(
            final Graph graph,
            final UserRepository userRepository,
            final WorkspaceRepository workspaceRepository,
            final Configuration configuration) {
        super(userRepository, workspaceRepository, configuration);
        this.graph = graph;
    }

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, HandlerChain chain) throws Exception {
        String[] vertexStringIds = getRequiredParameterArray(request, "vertexIds[]");
        boolean fallbackToPublic = getOptionalParameterBoolean(request, "fallbackToPublic", false);
        User user = getUser(request);
        Authorizations authorizations = getAuthorizations(request, fallbackToPublic, user);
        String workspaceId = getWorkspaceId(request);

        Iterable<Object> vertexIds = new ConvertingIterable<String, Object>(toIterable(vertexStringIds)) {
            @Override
            protected Object convert(String s) {
                return s;
            }
        };

        Iterable<Vertex> graphVertices = graph.getVertices(vertexIds, authorizations);
        JSONObject results = new JSONObject();
        JSONArray vertices = new JSONArray();
        results.put("vertices", vertices);
        for (Vertex v : graphVertices) {
            vertices.put(JsonSerializer.toJson(v, workspaceId));
        }

        respondWithJson(response, results);
    }

    private Authorizations getAuthorizations(HttpServletRequest request, boolean fallbackToPublic, User user) {
        Authorizations authorizations;
        try {
            authorizations = getAuthorizations(request, user);
        } catch (LumifyAccessDeniedException ex) {
            if (fallbackToPublic) {
                authorizations = getUserRepository().getAuthorizations(user);
            } else {
                throw ex;
            }
        }
        return authorizations;
    }

    private String getWorkspaceId(HttpServletRequest request) {
        String workspaceId;
        try {
            workspaceId = getActiveWorkspaceId(request);
        } catch (LumifyException ex) {
            workspaceId = null;
        }
        return workspaceId;
    }
}

@@ -1625,32 +1625,35 @@
 quest);%0A        
+Get
 Authorizations a
@@ -1642,34 +1642,43 @@
 etAuthorizations
- a
+Result getA
 uthorizations = 
@@ -1666,32 +1666,38 @@
 etAuthorizations
+Result
  = getAuthorizat
@@ -2090,16 +2090,40 @@
 texIds, 
+getAuthorizationsResult.
 authoriz
@@ -2263,24 +2263,107 @@
  vertices);%0A
+        results.put(%22requiredFallback%22, getAuthorizationsResult.requiredFallback);%0A
         for 
@@ -2530,16 +2530,19 @@
 private 
+Get
 Authoriz
@@ -2547,16 +2547,22 @@
 izations
+Result
  getAuth
@@ -2647,16 +2647,19 @@
         
+Get
 Authoriz
@@ -2664,31 +2664,102 @@
 izations
- authorizations
+Result result = new GetAuthorizationsResult();%0A        result.requiredFallback = false
 ;%0A      
@@ -2770,32 +2770,39 @@
 y %7B%0A            
+result.
 authorizations =
@@ -2939,16 +2939,23 @@
         
+result.
 authoriz
@@ -3004,24 +3004,72 @@
 ions(user);%0A
+                result.requiredFallback = true;%0A
             
@@ -3142,30 +3142,22 @@
  return 
-authorizations
+result
 ;%0A    %7D%0A
@@ -3434,11 +3434,156 @@
 d;%0A    %7D
+%0A%0A    private static class GetAuthorizationsResult %7B%0A        public Authorizations authorizations;%0A        public boolean requiredFallback;%0A    %7D
 %0A%7D%0A

add 'requiredFallback' to JSON result to allow front-end to display a message