/**
 * 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.AtlasClient;
import org.apache.atlas.AtlasException;
import org.apache.atlas.TestUtils;
import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.typesystem.IReferenceableInstance;
import org.apache.atlas.typesystem.IStruct;
import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.ITypedStruct;
import org.apache.atlas.typesystem.persistence.Id;
import org.apache.atlas.typesystem.persistence.Id.EntityState;
import org.apache.atlas.typesystem.types.TypeSystem;
import org.testng.Assert;

import java.util.List;
import java.util.Map;

import static org.apache.atlas.TestUtils.COLUMNS_ATTR_NAME;
import static org.apache.atlas.TestUtils.NAME;
import static org.apache.atlas.TestUtils.PII;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;

public class GraphBackedRepositorySoftDeleteTest extends GraphBackedMetadataRepositoryDeleteTestBase {
    @Override
    DeleteHandler getDeleteHandler(TypeSystem typeSystem) {
        return new SoftDeleteHandler(typeSystem);
    }

    @Override
    protected void assertTestDeleteEntityWithTraits(String guid) throws Exception {
        ITypedReferenceableInstance instance = repositoryService.getEntityDefinition(guid);
        assertTrue(instance.getTraits().contains(PII));
    }

    @Override
    protected void assertTableForTestDeleteReference(String tableId) throws Exception  {
        ITypedReferenceableInstance table = repositoryService.getEntityDefinition(tableId);
        assertNotNull(table.get(NAME));
        assertNotNull(table.get("description"));
        assertNotNull(table.get("type"));
        assertNotNull(table.get("tableType"));
        assertNotNull(table.get("created"));

        Id dbId = (Id) table.get("database");
        assertNotNull(dbId);

        ITypedReferenceableInstance db = repositoryService.getEntityDefinition(dbId.getId()._getId());
        assertNotNull(db);
        assertEquals(db.getId().getState(), Id.EntityState.ACTIVE);
    }

    @Override
    protected void assertColumnForTestDeleteReference(ITypedReferenceableInstance tableInstance) throws AtlasException {
        List<ITypedReferenceableInstance> columns =
                (List<ITypedReferenceableInstance>) tableInstance.get(COLUMNS_ATTR_NAME);
        assertEquals(columns.size(), 1);
        assertEquals(columns.get(0).getId().getState(), Id.EntityState.DELETED);
    }

    @Override
    protected void assertProcessForTestDeleteReference(ITypedReferenceableInstance expected) throws Exception {
        ITypedReferenceableInstance process = repositoryService.getEntityDefinition(expected.getId()._getId());
        List<ITypedReferenceableInstance> outputs =
                (List<ITypedReferenceableInstance>) process.get(AtlasClient.PROCESS_ATTRIBUTE_OUTPUTS);
        List<ITypedReferenceableInstance> expectedOutputs =
                (List<ITypedReferenceableInstance>) process.get(AtlasClient.PROCESS_ATTRIBUTE_OUTPUTS);
        assertEquals(outputs.size(), expectedOutputs.size());
    }

    @Override
    protected void assertEntityDeleted(String id) throws Exception {
        ITypedReferenceableInstance entity = repositoryService.getEntityDefinition(id);
        assertEquals(entity.getId().getState(), Id.EntityState.DELETED);
    }

    @Override
    protected void assertDeletedColumn(ITypedReferenceableInstance tableInstance) throws AtlasException {
        List<IReferenceableInstance> columns = (List<IReferenceableInstance>) tableInstance.get(COLUMNS_ATTR_NAME);
        assertEquals(columns.size(), 3);
        assertEquals(columns.get(0).getId().getState(), Id.EntityState.DELETED);
    }

    @Override
    protected void assertTestDeleteEntities(ITypedReferenceableInstance expected) throws Exception {
        //Assert that the deleted table can be fully constructed back
        ITypedReferenceableInstance table = repositoryService.getEntityDefinition(expected.getId()._getId());
        List<ITypedReferenceableInstance> columns =
                (List<ITypedReferenceableInstance>) table.get(TestUtils.COLUMNS_ATTR_NAME);
        List<ITypedReferenceableInstance> expectedColumns =
                (List<ITypedReferenceableInstance>) table.get(TestUtils.COLUMNS_ATTR_NAME);
        assertEquals(columns.size(), expectedColumns.size());
        assertNotNull(table.get("database"));
    }

    @Override
    protected void assertVerticesDeleted(List<AtlasVertex> vertices) {
        for (AtlasVertex vertex : vertices) {
            assertEquals(GraphHelper.getSingleValuedProperty(vertex, Constants.STATE_PROPERTY_KEY, String.class), Id.EntityState.DELETED.name());
        }
    }

    @Override
    protected void assertTestUpdateEntity_MultiplicityOneNonCompositeReference(String janeGuid) throws Exception {
        // Verify Jane's subordinates reference cardinality is still 2.
        ITypedReferenceableInstance jane = repositoryService.getEntityDefinition(janeGuid);
        List<ITypedReferenceableInstance> subordinates = (List<ITypedReferenceableInstance>) jane.get("subordinates");
        Assert.assertEquals(subordinates.size(), 2);
    }

    @Override
    protected void assertJohnForTestDisconnectBidirectionalReferences(ITypedReferenceableInstance john, String janeGuid)
            throws Exception {
        Id mgr = (Id) john.get("manager");
        assertNotNull(mgr);
        assertEquals(mgr._getId(), janeGuid);
        assertEquals(mgr.getState(), Id.EntityState.DELETED);
    }

    @Override
    protected void assertMaxForTestDisconnectBidirectionalReferences(Map<String, String> nameGuidMap) throws Exception {
        // Verify that the Department.employees reference to the deleted employee
        // was disconnected.
        ITypedReferenceableInstance hrDept = repositoryService.getEntityDefinition(nameGuidMap.get("hr"));
        List<ITypedReferenceableInstance> employees = (List<ITypedReferenceableInstance>) hrDept.get("employees");
        Assert.assertEquals(employees.size(), 4);
        String maxGuid = nameGuidMap.get("Max");
        for (ITypedReferenceableInstance employee : employees) {
            if (employee.getId()._getId().equals(maxGuid)) {
                assertEquals(employee.getId().getState(), Id.EntityState.DELETED);
            }
        }

        // Verify that the Manager.subordinates still references deleted employee
        ITypedReferenceableInstance jane = repositoryService.getEntityDefinition(nameGuidMap.get("Jane"));
        List<ITypedReferenceableInstance> subordinates = (List<ITypedReferenceableInstance>) jane.get("subordinates");
        assertEquals(subordinates.size(), 2);
        for (ITypedReferenceableInstance subordinate : subordinates) {
            if (subordinate.getId()._getId().equals(maxGuid)) {
                assertEquals(subordinate.getId().getState(), Id.EntityState.DELETED);
            }
        }

        // Verify that max's Person.mentor unidirectional reference to john was disconnected.
        ITypedReferenceableInstance john = repositoryService.getEntityDefinition(nameGuidMap.get("John"));
        Id mentor = (Id) john.get("mentor");
        assertEquals(mentor._getId(), maxGuid);
        assertEquals(mentor.getState(), Id.EntityState.DELETED);
    }

    @Override
    protected void assertTestDisconnectUnidirectionalArrayReferenceFromClassType(
            List<ITypedReferenceableInstance> columns, String columnGuid) {
        Assert.assertEquals(columns.size(), 5);
        for (ITypedReferenceableInstance column : columns) {
            if (column.getId()._getId().equals(columnGuid)) {
                assertEquals(column.getId().getState(), Id.EntityState.DELETED);
            } else {
                assertEquals(column.getId().getState(), Id.EntityState.ACTIVE);
            }
        }

    }

    @Override
    protected void assertTestDisconnectUnidirectionalArrayReferenceFromStructAndTraitTypes(String structContainerGuid)
            throws Exception {
        // Verify that the unidirectional references from the struct and trait instances
        // to the deleted entities were not disconnected.
        ITypedReferenceableInstance structContainerConvertedEntity =
                repositoryService.getEntityDefinition(structContainerGuid);
        ITypedStruct struct = (ITypedStruct) structContainerConvertedEntity.get("struct");
        assertNotNull(struct.get("target"));
        IStruct trait = structContainerConvertedEntity.getTrait("TestTrait");
        assertNotNull(trait);
        assertNotNull(trait.get("target"));

    }

    @Override
    protected void assertTestDisconnectMapReferenceFromClassType(String mapOwnerGuid) throws Exception {
        ITypedReferenceableInstance mapOwnerInstance = repositoryService.getEntityDefinition(mapOwnerGuid);
        Map<String, ITypedReferenceableInstance> map =
                (Map<String, ITypedReferenceableInstance>) mapOwnerInstance.get("map");
        assertNotNull(map);
        assertEquals(map.size(), 1);
        Map<String, ITypedReferenceableInstance> biMap =
                (Map<String, ITypedReferenceableInstance>) mapOwnerInstance.get("biMap");
        assertNotNull(biMap);
        assertEquals(biMap.size(), 1);
    }

    @Override
    protected void assertTestDeleteTargetOfMultiplicityRequiredReference() throws Exception {
        // No-op - it's ok that no exception was thrown if soft deletes are enabled.
    }

    @Override
    protected void assertTestLowerBoundsIgnoredOnDeletedEntities(List<ITypedReferenceableInstance> employees) {

        Assert.assertEquals(employees.size(), 4, "References to deleted employees should not have been disconnected with soft deletes enabled");
    }

    @Override
    protected void assertTestLowerBoundsIgnoredOnCompositeDeletedEntities(String hrDeptGuid) throws Exception {

        ITypedReferenceableInstance hrDept = repositoryService.getEntityDefinition(hrDeptGuid);
        Assert.assertEquals(hrDept.getId().getState(), EntityState.DELETED);
    }

    @Override
    protected void verifyTestDeleteEntityWithDuplicateReferenceListElements(List columnsPropertyValue) {

        // With soft deletes enabled, verify that edge IDs for deleted edges
        // were not removed from the array property list.
        Assert.assertEquals(columnsPropertyValue.size(), 4);
    }
}
