package com.altamiracorp.lumify.core.model.workspace;

import com.altamiracorp.lumify.core.model.ontology.Concept;
import com.altamiracorp.lumify.core.model.ontology.OntologyRepository;
import com.altamiracorp.lumify.core.model.ontology.Relationship;
import com.altamiracorp.lumify.core.model.user.AuthorizationRepository;
import com.altamiracorp.lumify.core.model.user.InMemoryAuthorizationRepository;
import com.altamiracorp.lumify.core.model.user.UserRepository;
import com.altamiracorp.lumify.core.user.User;
import com.altamiracorp.securegraph.Graph;
import com.altamiracorp.securegraph.Vertex;
import com.altamiracorp.securegraph.id.IdGenerator;
import com.altamiracorp.securegraph.inmemory.InMemoryAuthorizations;
import com.altamiracorp.securegraph.inmemory.InMemoryGraph;
import com.altamiracorp.securegraph.inmemory.InMemoryGraphConfiguration;
import com.altamiracorp.securegraph.search.DefaultSearchIndex;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.HashMap;

import static org.junit.Assert.*;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class WorkspaceRepositoryTest {
    private Graph graph;

    @Mock
    private OntologyRepository ontologyRepository;

    @Mock
    private Concept entityConcept;

    @Mock
    private Concept workspaceConcept;

    @Mock
    private Relationship workspaceToEntityRelationship;

    @Mock
    private Relationship workspaceToUserRelationship;

    @Mock
    private UserRepository userRepository;

    @Mock
    private User user;

    @Mock
    private Vertex userVertex;

    @Mock
    private IdGenerator idGenerator;

    private WorkspaceRepository workspaceRepository;
    private AuthorizationRepository authorizationRepository;

    @Before
    public void setup() {
        InMemoryGraphConfiguration config = new InMemoryGraphConfiguration(new HashMap());
        graph = new InMemoryGraph(config, idGenerator, new DefaultSearchIndex(config.getConfig()));
        authorizationRepository = new InMemoryAuthorizationRepository();

        when(ontologyRepository.getConceptByName(eq(OntologyRepository.TYPE_ENTITY))).thenReturn(entityConcept);

        when(ontologyRepository.getOrCreateConcept((Concept) isNull(), eq(WorkspaceRepository.WORKSPACE_CONCEPT_NAME), anyString())).thenReturn(workspaceConcept);
        when(workspaceConcept.getId()).thenReturn(WorkspaceRepository.WORKSPACE_CONCEPT_NAME);

        when(ontologyRepository.getOrCreateRelationshipType(eq(workspaceConcept), eq(entityConcept), eq(WorkspaceRepository.WORKSPACE_TO_ENTITY_RELATIONSHIP_NAME), anyString())).thenReturn(workspaceToEntityRelationship);

        when(ontologyRepository.getOrCreateRelationshipType(eq(workspaceConcept), eq(entityConcept), eq(WorkspaceRepository.WORKSPACE_TO_USER_RELATIONSHIP_NAME), anyString())).thenReturn(workspaceToUserRelationship);

        workspaceRepository = new WorkspaceRepository(graph, ontologyRepository, userRepository, authorizationRepository);

        String userId = "testUser";
        when(user.getUserId()).thenReturn(userId);
        when(userRepository.findById(eq(userId))).thenReturn(userVertex);
    }

    @Test
    public void testAddWorkspace() {
        String workspaceId = "testWorkspaceId";
        when(idGenerator.nextId()).thenReturn(workspaceId);

        Workspace workspace = workspaceRepository.add("workspace1", user);
        verify(userRepository, times(1)).addAuthorization((Vertex) any(), eq(WorkspaceRepository.WORKSPACE_ID_PREFIX + workspaceId));

        assertNull("Should not have access", graph.getVertex(workspace.getId(), new InMemoryAuthorizations()));
        assertNull("Should not have access", graph.getVertex(workspace.getId(), new InMemoryAuthorizations(WorkspaceRepository.VISIBILITY_STRING)));
        InMemoryAuthorizations authorizations = new InMemoryAuthorizations(WorkspaceRepository.VISIBILITY_STRING, workspace.getId());
        assertNotNull("Should have access", graph.getVertex(workspace.getId(), authorizations));

        when(userRepository.getAuthorizations(eq(user), eq(WorkspaceRepository.VISIBILITY_STRING), eq(workspace.getId()))).thenReturn(authorizations);
        Workspace foundWorkspace = workspaceRepository.findById(workspace.getId(), user);
        assertEquals(workspace.getId(), foundWorkspace.getId());
    }
}

@@ -510,51 +510,8 @@
 er;%0A
-import com.altamiracorp.securegraph.Graph;%0A
 impo
@@ -546,24 +546,24 @@
 aph.Vertex;%0A
+
 import com.a
@@ -1373,16 +1373,24 @@
 private 
+InMemory
 Graph gr
@@ -3428,24 +3428,150 @@
 rkspace() %7B%0A
+        int startingVertexCount = graph.getAllVertices().size();%0A        int startingEdgeCount = graph.getAllEdges().size();%0A%0A
         Stri
@@ -4603,32 +4603,32 @@
 getId(), user);%0A
-
         assertEq
@@ -4671,21 +4671,246 @@
 ce.getId());
+%0A%0A        assertEquals(startingVertexCount + 1, graph.getAllVertices().size()); // +1 = the workspace vertex%0A        assertEquals(startingEdgeCount + 1, graph.getAllEdges().size()); // +1 = the edge between workspace and user
 %0A    %7D%0A%7D%0A

add test for vertex and edge counts