/**
 * 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
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.store.graph;

import com.google.inject.Inject;
import org.apache.atlas.TestModules;
import org.apache.atlas.TestUtilsV2;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.SearchFilter;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.atlas.store.AtlasTypeDefStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.testng.Assert.*;

@Guice(modules = TestModules.TestOnlyModule.class)
public class AtlasTypeDefGraphStoreTest {
    private static final Logger LOG = LoggerFactory.getLogger(AtlasTypeDefGraphStoreTest.class);

    @Inject
    private
    AtlasTypeDefStore typeDefStore;

    @Test(priority = 1)
    public void testGet() {
        try {
            AtlasTypesDef typesDef = typeDefStore.searchTypesDef(new SearchFilter());
            assertNotNull(typesDef.getEnumDefs());
            assertEquals(typesDef.getStructDefs().size(), 0);
            assertNotNull(typesDef.getStructDefs());
            assertEquals(typesDef.getClassificationDefs().size(), 0);
            assertNotNull(typesDef.getClassificationDefs());
            assertEquals(typesDef.getEntityDefs().size(), 0);
            assertNotNull(typesDef.getEntityDefs());
        } catch (AtlasBaseException e) {
            fail("Search of types shouldn't have failed");
        }
    }

    @Test(dataProvider = "invalidGetProvider", priority = 2)
    public void testInvalidGet(String name, String guid){
        try {
            assertNull(typeDefStore.getEnumDefByName(name));
            fail("Exception expected for invalid name");
        } catch (AtlasBaseException e) {
        }

        try {
            assertNull(typeDefStore.getEnumDefByGuid(guid));
            fail("Exception expected for invalid guid");
        } catch (AtlasBaseException e) {
        }

        try {
            assertNull(typeDefStore.getStructDefByName(name));
            fail("Exception expected for invalid name");
        } catch (AtlasBaseException e) {
        }

        try {
            assertNull(typeDefStore.getStructDefByGuid(guid));
            fail("Exception expected for invalid guid");
        } catch (AtlasBaseException e) {
        }

        try {
            assertNull(typeDefStore.getClassificationDefByName(name));
            fail("Exception expected for invalid name");
        } catch (AtlasBaseException e) {
        }

        try {
            assertNull(typeDefStore.getClassificationDefByGuid(guid));
            fail("Exception expected for invalid guid");
        } catch (AtlasBaseException e) {
        }

        try {
            assertNull(typeDefStore.getEntityDefByName(name));
            fail("Exception expected for invalid name");
        } catch (AtlasBaseException e) {
        }

        try {
            assertNull(typeDefStore.getEntityDefByGuid(guid));
            fail("Exception expected for invalid guid");
        } catch (AtlasBaseException e) {
        }
    }

    @DataProvider
    public Object[][] invalidGetProvider(){
        return new Object[][] {
                {"name1", "guid1"},
                {"", ""},
                {null, null}
        };
    }

    @DataProvider
    public Object[][] validCreateDeptTypes(){
        return new Object[][] {
                {TestUtilsV2.defineDeptEmployeeTypes()}
        };
    }

    @DataProvider
    public Object[][] validUpdateDeptTypes(){
        AtlasTypesDef typesDef = TestUtilsV2.defineValidUpdatedDeptEmployeeTypes();
        return new Object[][] {
                {typesDef}
        };
    }

    @DataProvider
    public Object[][] allCreatedTypes(){
        // Capture all the types that are getting created or updated here.
        AtlasTypesDef updatedTypeDefs = TestUtilsV2.defineValidUpdatedDeptEmployeeTypes();
        AtlasTypesDef allTypeDefs = new AtlasTypesDef();
        allTypeDefs.getEnumDefs().addAll(updatedTypeDefs.getEnumDefs());
        allTypeDefs.getStructDefs().addAll(updatedTypeDefs.getStructDefs());
        allTypeDefs.getClassificationDefs().addAll(updatedTypeDefs.getClassificationDefs());
        allTypeDefs.getEntityDefs().addAll(updatedTypeDefs.getEntityDefs());
        allTypeDefs.getEntityDefs().addAll(TestUtilsV2.getEntityWithValidSuperType());
        return new Object[][] {{allTypeDefs}};
    }

    @DataProvider
    public Object[][] invalidCreateTypes(){
        // TODO: Create invalid type in TestUtilsV2
        return new Object[][] {
        };
    }

    @DataProvider
    public Object[][] invalidUpdateTypes(){
        return new Object[][] {
                {TestUtilsV2.defineInvalidUpdatedDeptEmployeeTypes()}
        };
    }

    @Test(dependsOnMethods = {"testGet"}, dataProvider = "validCreateDeptTypes")
    public void testCreateDept(AtlasTypesDef atlasTypesDef) {
        AtlasTypesDef existingTypesDef = null;
        try {
            existingTypesDef = typeDefStore.searchTypesDef(new SearchFilter());
        } catch (AtlasBaseException e) {
            // ignore
        }

        assertNotEquals(atlasTypesDef, existingTypesDef, "Types to be created already exist in the system");
        AtlasTypesDef createdTypesDef = null;
        try {
            createdTypesDef = typeDefStore.createTypesDef(atlasTypesDef);
            assertNotNull(createdTypesDef);
            assertTrue(createdTypesDef.getEnumDefs().containsAll(atlasTypesDef.getEnumDefs()), "EnumDefs create failed");
            assertTrue(createdTypesDef.getClassificationDefs().containsAll(atlasTypesDef.getClassificationDefs()), "ClassificationDef create failed");
            assertTrue(createdTypesDef.getStructDefs().containsAll(atlasTypesDef.getStructDefs()), "StructDef creation failed");
            Assert.assertEquals(createdTypesDef.getEntityDefs(), atlasTypesDef.getEntityDefs());

        } catch (AtlasBaseException e) {
            fail("Creation of Types should've been a success", e);
        }
    }

    @Test(dependsOnMethods = {"testCreateDept"}, dataProvider = "validUpdateDeptTypes")
    public void testUpdate(AtlasTypesDef atlasTypesDef){
        try {
            AtlasTypesDef updatedTypesDef = typeDefStore.updateTypesDef(atlasTypesDef);
            assertNotNull(updatedTypesDef);

            assertEquals(updatedTypesDef.getEnumDefs().size(), atlasTypesDef.getEnumDefs().size(), "EnumDefs update failed");
            assertEquals(updatedTypesDef.getClassificationDefs().size(), atlasTypesDef.getClassificationDefs().size(), "ClassificationDef update failed");
            assertEquals(updatedTypesDef.getStructDefs().size(), atlasTypesDef.getStructDefs().size(), "StructDef update failed");
            assertEquals(updatedTypesDef.getEntityDefs().size(), atlasTypesDef.getEntityDefs().size(), "EntityDef update failed");

            // Try another update round by name and GUID
            for (AtlasEnumDef enumDef : updatedTypesDef.getEnumDefs()) {
                AtlasEnumDef updated = typeDefStore.updateEnumDefByGuid(enumDef.getGuid(), enumDef);
                assertNotNull(updated);
            }
            for (AtlasEnumDef enumDef : atlasTypesDef.getEnumDefs()) {
                AtlasEnumDef updated = typeDefStore.updateEnumDefByName(enumDef.getName(), enumDef);
                assertNotNull(updated);
            }

            // Try another update round by name and GUID
            for (AtlasClassificationDef classificationDef : updatedTypesDef.getClassificationDefs()) {
                AtlasClassificationDef updated = typeDefStore.updateClassificationDefByGuid(classificationDef.getGuid(), classificationDef);
                assertNotNull(updated);
            }
            for (AtlasClassificationDef classificationDef : atlasTypesDef.getClassificationDefs()) {
                AtlasClassificationDef updated = typeDefStore.updateClassificationDefByName(classificationDef.getName(), classificationDef);
                assertNotNull(updated);
            }

            // Try another update round by name and GUID
            for (AtlasStructDef structDef : updatedTypesDef.getStructDefs()) {
                AtlasStructDef updated = typeDefStore.updateStructDefByGuid(structDef.getGuid(), structDef);
                assertNotNull(updated);
            }
            for (AtlasStructDef structDef : atlasTypesDef.getStructDefs()) {
                AtlasStructDef updated = typeDefStore.updateStructDefByName(structDef.getName(), structDef);
                assertNotNull(updated);
            }

            // Try another update round by name and GUID
            for (AtlasEntityDef entityDef : updatedTypesDef.getEntityDefs()) {
                AtlasEntityDef updated = typeDefStore.updateEntityDefByGuid(entityDef.getGuid(), entityDef);
                assertNotNull(updated);
            }
            for (AtlasEntityDef entityDef : atlasTypesDef.getEntityDefs()) {
                AtlasEntityDef updated = typeDefStore.updateEntityDefByName(entityDef.getName(), entityDef);
                assertNotNull(updated);
            }

        } catch (AtlasBaseException e) {
            fail("TypeDef updates should've succeeded");
        }
    }

    @Test(enabled = false, dependsOnMethods = {"testCreateDept"})
    public void testUpdateWithMandatoryFields(){
        AtlasTypesDef atlasTypesDef = TestUtilsV2.defineInvalidUpdatedDeptEmployeeTypes();
        List<AtlasEnumDef> enumDefsToUpdate = atlasTypesDef.getEnumDefs();
        List<AtlasClassificationDef> classificationDefsToUpdate = atlasTypesDef.getClassificationDefs();
        List<AtlasStructDef> structDefsToUpdate = atlasTypesDef.getStructDefs();
        List<AtlasEntityDef> entityDefsToUpdate = atlasTypesDef.getEntityDefs();

        AtlasTypesDef onlyEnums = new AtlasTypesDef(enumDefsToUpdate,
                Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST);

        AtlasTypesDef onlyStructs = new AtlasTypesDef(Collections.EMPTY_LIST,
                structDefsToUpdate, Collections.EMPTY_LIST, Collections.EMPTY_LIST);

        AtlasTypesDef onlyClassification = new AtlasTypesDef(Collections.EMPTY_LIST,
                Collections.EMPTY_LIST, classificationDefsToUpdate, Collections.EMPTY_LIST);

        AtlasTypesDef onlyEntities = new AtlasTypesDef(Collections.EMPTY_LIST,
                Collections.EMPTY_LIST, Collections.EMPTY_LIST, entityDefsToUpdate);

        try {
            AtlasTypesDef updated = typeDefStore.updateTypesDef(onlyEnums);
            assertNotNull(updated);
        } catch (AtlasBaseException ignored) {}

        try {
            AtlasTypesDef updated = typeDefStore.updateTypesDef(onlyClassification);
            assertNotNull(updated);
            assertEquals(updated.getClassificationDefs().size(), 0, "Updates should've failed");
        } catch (AtlasBaseException ignored) {}

        try {
            AtlasTypesDef updated = typeDefStore.updateTypesDef(onlyStructs);
            assertNotNull(updated);
            assertEquals(updated.getStructDefs().size(), 0, "Updates should've failed");
        } catch (AtlasBaseException ignored) {}

        try {
            AtlasTypesDef updated = typeDefStore.updateTypesDef(onlyEntities);
            assertNotNull(updated);
            assertEquals(updated.getEntityDefs().size(), 0, "Updates should've failed");
        } catch (AtlasBaseException ignored) {}
    }

    // This should run after all the update calls
    @Test(dependsOnMethods = {"testUpdate"}, dataProvider = "allCreatedTypes")
    public void testDelete(AtlasTypesDef atlasTypesDef){
        try {
            typeDefStore.deleteTypesDef(atlasTypesDef);
        } catch (AtlasBaseException e) {
            fail("Deletion should've succeeded");
        }
    }

    @Test(dependsOnMethods = "testGet")
    public void testCreateWithValidAttributes(){
        AtlasTypesDef hiveTypes = TestUtilsV2.defineHiveTypes();
        try {
            AtlasTypesDef createdTypes = typeDefStore.createTypesDef(hiveTypes);
            assertEquals(hiveTypes.getEnumDefs(), createdTypes.getEnumDefs(), "Data integrity issue while persisting");
            assertEquals(hiveTypes.getStructDefs(), createdTypes.getStructDefs(), "Data integrity issue while persisting");
            assertEquals(hiveTypes.getClassificationDefs(), createdTypes.getClassificationDefs(), "Data integrity issue while persisting");
            assertEquals(hiveTypes.getEntityDefs(), createdTypes.getEntityDefs(), "Data integrity issue while persisting");
        } catch (AtlasBaseException e) {
            fail("Hive Type creation should've succeeded");
        }
    }

    @Test(enabled = false)
    public void testCreateWithInvalidAttributes(){
    }

    @Test(dependsOnMethods = "testGet")
    public void testCreateWithValidSuperTypes(){
        // Test Classification with supertype
        List<AtlasClassificationDef> classificationDefs = TestUtilsV2.getClassificationWithValidSuperType();

        AtlasTypesDef toCreate = new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(),
                Collections.<AtlasStructDef>emptyList(),
                classificationDefs,
                Collections.<AtlasEntityDef>emptyList());
        try {
            AtlasTypesDef created = typeDefStore.createTypesDef(toCreate);
            assertEquals(created.getClassificationDefs(), toCreate.getClassificationDefs(),
                    "Classification creation with valid supertype should've succeeded");
        } catch (AtlasBaseException e) {
            fail("Classification creation with valid supertype should've succeeded");
        }

        // Test Entity with supertype
        List<AtlasEntityDef> entityDefs = TestUtilsV2.getEntityWithValidSuperType();
        toCreate = new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(),
                Collections.<AtlasStructDef>emptyList(),
                Collections.<AtlasClassificationDef>emptyList(),
                entityDefs);
        try {
            AtlasTypesDef created = typeDefStore.createTypesDef(toCreate);
            assertEquals(created.getEntityDefs(), toCreate.getEntityDefs(),
                    "Entity creation with valid supertype should've succeeded");
        } catch (AtlasBaseException e) {
            fail("Entity creation with valid supertype should've succeeded");
        }
    }

    @Test(dependsOnMethods = "testGet")
    public void testCreateWithInvalidSuperTypes(){
        AtlasTypesDef typesDef;

        // Test Classification with supertype
        AtlasClassificationDef classificationDef = TestUtilsV2.getClassificationWithInvalidSuperType();
        typesDef = new AtlasTypesDef();
        typesDef.getClassificationDefs().add(classificationDef);
        try {
            AtlasTypesDef created = typeDefStore.createTypesDef(typesDef);
            fail("Classification creation with invalid supertype should've failed");
        } catch (AtlasBaseException e) {
            typesDef = null;
        }

        // Test Entity with supertype
        AtlasEntityDef entityDef = TestUtilsV2.getEntityWithInvalidSuperType();
        typesDef = new AtlasTypesDef();
        typesDef.getEntityDefs().add(entityDef);
        try {
            AtlasTypesDef created = typeDefStore.createTypesDef(typesDef);
            fail("Entity creation with invalid supertype should've failed");
        } catch (AtlasBaseException e) {}

    }

    @Test(dependsOnMethods = "testGet")
    public void testSearchFunctionality() {
        SearchFilter searchFilter = new SearchFilter();
        searchFilter.setParam(SearchFilter.PARAM_SUPERTYPE, "Person");

        try {
            AtlasTypesDef typesDef = typeDefStore.searchTypesDef(searchFilter);
            assertNotNull(typesDef);
            assertNotNull(typesDef.getEntityDefs());
            assertEquals(typesDef.getEntityDefs().size(), 3);
        } catch (AtlasBaseException e) {
            fail("Search should've succeeded", e);
        }
    }

    @Test
    public void testTypeDeletionAndRecreate() {
        AtlasClassificationDef aTag = new AtlasClassificationDef("testTag");
        AtlasAttributeDef attributeDef = new AtlasAttributeDef("testAttribute", "string", true,
                AtlasAttributeDef.Cardinality.SINGLE, 0, 1,
                false, true,
                Collections.<AtlasStructDef.AtlasConstraintDef>emptyList());
        aTag.addAttribute(attributeDef);

        AtlasTypesDef typesDef = new AtlasTypesDef();
        typesDef.setClassificationDefs(Arrays.asList(aTag));

        try {
            typeDefStore.createTypesDef(typesDef);
        } catch (AtlasBaseException e) {
            fail("Tag creation should've succeeded");
        }

        try {
            typeDefStore.deleteTypesDef(typesDef);
        } catch (AtlasBaseException e) {
            fail("Tag deletion should've succeeded");
        }

        aTag = new AtlasClassificationDef("testTag");
        attributeDef = new AtlasAttributeDef("testAttribute", "int", true,
                AtlasAttributeDef.Cardinality.SINGLE, 0, 1,
                false, true,
                Collections.<AtlasStructDef.AtlasConstraintDef>emptyList());
        aTag.addAttribute(attributeDef);
        typesDef.setClassificationDefs(Arrays.asList(aTag));

        try {
            typeDefStore.createTypesDef(typesDef);
        } catch (AtlasBaseException e) {
            fail("Tag re-creation should've succeeded");
        }
    }

}