/**
 * 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.repository.graph;

import org.apache.atlas.AtlasException;
import org.apache.atlas.TestModules;
import org.apache.atlas.TestUtils;
import org.apache.atlas.repository.graph.GraphHelper.VertexInfo;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.services.MetadataService;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.Referenceable;
import org.apache.atlas.typesystem.TypesDef;
import org.apache.atlas.typesystem.exception.TypeNotFoundException;
import org.apache.atlas.typesystem.json.InstanceSerialization;
import org.apache.atlas.typesystem.json.TypesSerialization;
import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.Multiplicity;
import org.apache.atlas.typesystem.types.TypeSystem;
import org.codehaus.jettison.json.JSONArray;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.testng.Assert.*;

@Guice(modules = TestModules.TestOnlyModule.class)
public class GraphHelperTest {


    @DataProvider(name = "encodeDecodeTestData")
    private Object[][] createTestData() {
        return new Object[][]{
                {"hivedb$", "hivedb_d"},
                {"hivedb", "hivedb"},
                {"{hivedb}", "_ohivedb_c"},
                {"%hivedb}", "_phivedb_c"},
                {"\"hivedb\"", "_qhivedb_q"},
                {"\"$%{}", "_q_d_p_o_c"},
                {"", ""},
                {"  ", "  "},
                {"\n\r", "\n\r"},
                {null, null}
        };
    }

    @Inject
    private MetadataService metadataService;

    @Inject
    private GraphBackedMetadataRepository repositoryService;

    private TypeSystem typeSystem;

    @Inject
    private AtlasTypeRegistry typeRegistry;

    @BeforeClass
    public void setUp() throws Exception {
        typeSystem = TypeSystem.getInstance();
        typeSystem.reset();

        new GraphBackedSearchIndexer(typeRegistry);
        TypesDef typesDef = TestUtils.defineHiveTypes();
        try {
            metadataService.getTypeDefinition(TestUtils.TABLE_TYPE);
        } catch (TypeNotFoundException e) {
            metadataService.createType(TypesSerialization.toJson(typesDef));
        }
        TestUtils.defineDeptEmployeeTypes(typeSystem);
    }

    @AfterClass
    public void tearDown() {
//        AtlasGraphProvider.cleanup();
    }

    @Test
    public void testGetInstancesByUniqueAttributes() throws Exception {

        GraphHelper helper = GraphHelper.getInstance();
        List<ITypedReferenceableInstance> instances =  new ArrayList<>();
        List<String> guids = new ArrayList<>();
        TypeSystem ts = TypeSystem.getInstance();
        ClassType dbType = ts.getDataType(ClassType.class, TestUtils.DATABASE_TYPE);

        for(int i = 0; i < 10; i++) {
            Referenceable db = TestUtils.createDBEntity();
            String guid = createInstance(db);
            ITypedReferenceableInstance instance = convert(db, dbType);
            instances.add(instance);
            guids.add(guid);
        }

        //lookup vertices via getVertexForInstanceByUniqueAttributes
        List<AtlasVertex> vertices = helper.getVerticesForInstancesByUniqueAttribute(dbType, instances);
        assertEquals(instances.size(), vertices.size());
        //assert vertex matches the vertex we get through getVertexForGUID
        for(int i = 0; i < instances.size(); i++) {
            String guid = guids.get(i);
            AtlasVertex foundVertex = vertices.get(i);
            AtlasVertex expectedVertex = helper.getVertexForGUID(guid);
            assertEquals(foundVertex, expectedVertex);
        }
    }
    @Test
    public void testGetVerticesForGUIDSWithDuplicates() throws Exception {
        ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(TypeSystem.getInstance());
        List<String> result = repositoryService.createEntities(hrDept).getCreatedEntities();
        String guid = result.get(0);
        Map<String, AtlasVertex> verticesForGUIDs = GraphHelper.getInstance().getVerticesForGUIDs(Arrays.asList(guid, guid));
        Assert.assertEquals(verticesForGUIDs.size(), 1);
        Assert.assertTrue(verticesForGUIDs.containsKey(guid));
    }
    @Test
    public void testGetCompositeGuidsAndVertices() throws Exception {
        ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem);
        List<String> createdGuids = repositoryService.createEntities(hrDept).getCreatedEntities();
        String deptGuid = null;
        Set<String> expectedGuids = new HashSet<>();

        for (String guid : createdGuids) {
            ITypedReferenceableInstance entityDefinition = repositoryService.getEntityDefinition(guid);
            expectedGuids.add(guid);
            if (entityDefinition.getId().getTypeName().equals(TestUtils.DEPARTMENT_TYPE)) {
                deptGuid = guid;
            }
        }
        AtlasVertex deptVertex = GraphHelper.getInstance().getVertexForGUID(deptGuid);
        Set<VertexInfo> compositeVertices = GraphHelper.getInstance().getCompositeVertices(deptVertex);
        HashMap<String, VertexInfo> verticesByGuid = new HashMap<>();
        for (VertexInfo vertexInfo: compositeVertices) {
            verticesByGuid.put(vertexInfo.getGuid(), vertexInfo);
        }

        // Verify compositeVertices has entries for all expected guids.
        Assert.assertEquals(compositeVertices.size(), expectedGuids.size());
        for (String expectedGuid : expectedGuids) {
            Assert.assertTrue(verticesByGuid.containsKey(expectedGuid));
        }
    }

    @Test(dataProvider = "encodeDecodeTestData")
    public void testEncodeDecode(String str, String expectedEncodedStr) throws Exception {
        String encodedStr = GraphHelper.encodePropertyKey(str);
        assertEquals(encodedStr, expectedEncodedStr);

        String decodedStr = GraphHelper.decodePropertyKey(encodedStr);
        assertEquals(decodedStr, str);
    }

    @Test
    public void testGetOutgoingEdgesByLabel() throws Exception {
        AtlasGraph graph = TestUtils.getGraph();
        AtlasVertex v1 = graph.addVertex();
        AtlasVertex v2 = graph.addVertex();
        graph.addEdge(v1, v2, "l1");
        graph.addEdge(v1, v2, "l2");

        Iterator<AtlasEdge> iterator = GraphHelper.getInstance().getOutGoingEdgesByLabel(v1, "l1");
        assertTrue(iterator.hasNext());
        assertTrue(iterator.hasNext());
        assertNotNull(iterator.next());
        assertNull(iterator.next());
        assertFalse(iterator.hasNext());
        assertFalse(iterator.hasNext());
    }

    private ITypedReferenceableInstance convert(Referenceable instance, ClassType type) throws AtlasException {

        return type.convert(instance, Multiplicity.REQUIRED);
    }

    private String createInstance(Referenceable entity) throws Exception {
        TestUtils.resetRequestContext();

        String entityjson = InstanceSerialization.toJson(entity, true);
        JSONArray entitiesJson = new JSONArray();
        entitiesJson.put(entityjson);
        List<String> guids = metadataService.createEntities(entitiesJson.toString()).getCreatedEntities();
        if (guids != null && guids.size() > 0) {
            return guids.get(guids.size() - 1);
        }
        return null;
    }
}
