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

import org.apache.atlas.EntityAuditEvent;
import org.apache.atlas.kafka.NotificationProvider;
import org.apache.atlas.notification.hook.HookNotification;
import org.apache.atlas.typesystem.Referenceable;
import org.apache.atlas.typesystem.persistence.Id;
import org.apache.atlas.web.integration.BaseResourceIT;
import org.codehaus.jettison.json.JSONArray;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.util.List;

import static org.testng.Assert.assertEquals;

public class NotificationHookConsumerIT extends BaseResourceIT {

    private static final String TEST_USER = "testuser";
    public static final String NAME = "name";
    public static final String DESCRIPTION = "description";
    public static final String QUALIFIED_NAME = "qualifiedName";
    public static final String CLUSTER_NAME = "clusterName";

    private NotificationInterface notificationInterface = NotificationProvider.get();

    @BeforeClass
    public void setUp() throws Exception {
        super.setUp();
        createTypeDefinitionsV1();
    }

    @AfterClass
    public void teardown() throws Exception {
        notificationInterface.close();
    }

    private void sendHookMessage(HookNotification.HookNotificationMessage message) throws NotificationException {
        notificationInterface.send(NotificationInterface.NotificationType.HOOK, message);
    }

    @Test
    public void testMessageHandleFailureConsumerContinues() throws Exception {
        //send invalid message - update with invalid type
        sendHookMessage(new HookNotification.EntityPartialUpdateRequest(TEST_USER, randomString(), null, null,
                new Referenceable(randomString())));

        //send valid message
        final Referenceable entity = new Referenceable(DATABASE_TYPE_BUILTIN);
        String dbName = "db" + randomString();
        entity.set(NAME, dbName);
        entity.set(DESCRIPTION, randomString());
        entity.set(QUALIFIED_NAME, dbName);
        entity.set(CLUSTER_NAME, randomString());
        sendHookMessage(new HookNotification.EntityCreateRequest(TEST_USER, entity));

        waitFor(MAX_WAIT_TIME, new Predicate() {
            @Override
            public boolean evaluate() throws Exception {
                JSONArray results = searchByDSL(String.format("%s where name='%s'", DATABASE_TYPE_BUILTIN, entity.get(NAME)));
                return results.length() == 1;
            }
        });
    }

    @Test
    public void testCreateEntity() throws Exception {
        final Referenceable entity = new Referenceable(DATABASE_TYPE_BUILTIN);
        String dbName = "db" + randomString();
        entity.set(NAME, dbName);
        entity.set(DESCRIPTION, randomString());
        entity.set(QUALIFIED_NAME, dbName);
        entity.set(CLUSTER_NAME, randomString());

        sendHookMessage(new HookNotification.EntityCreateRequest(TEST_USER, entity));

        waitFor(MAX_WAIT_TIME, new Predicate() {
            @Override
            public boolean evaluate() throws Exception {
                JSONArray results = searchByDSL(String.format("%s where qualifiedName='%s'", DATABASE_TYPE_BUILTIN, entity.get(QUALIFIED_NAME)));
                return results.length() == 1;
            }
        });

        //Assert that user passed in hook message is used in audit
        Referenceable instance = atlasClientV1.getEntity(DATABASE_TYPE_BUILTIN, QUALIFIED_NAME, (String) entity.get(QUALIFIED_NAME));
        List<EntityAuditEvent> events =
                atlasClientV1.getEntityAuditEvents(instance.getId()._getId(), (short) 1);
        assertEquals(events.size(), 1);
        assertEquals(events.get(0).getUser(), TEST_USER);
    }

    @Test
    public void testUpdateEntityPartial() throws Exception {
        final Referenceable entity = new Referenceable(DATABASE_TYPE_BUILTIN);
        final String dbName = "db" + randomString();
        entity.set(NAME, dbName);
        entity.set(DESCRIPTION, randomString());
        entity.set(QUALIFIED_NAME, dbName);
        entity.set(CLUSTER_NAME, randomString());

        atlasClientV1.createEntity(entity);

        final Referenceable newEntity = new Referenceable(DATABASE_TYPE_BUILTIN);
        newEntity.set("owner", randomString());
        sendHookMessage(
                new HookNotification.EntityPartialUpdateRequest(TEST_USER, DATABASE_TYPE_BUILTIN, QUALIFIED_NAME, dbName, newEntity));
        waitFor(MAX_WAIT_TIME, new Predicate() {
            @Override
            public boolean evaluate() throws Exception {
                Referenceable localEntity = atlasClientV1.getEntity(DATABASE_TYPE_BUILTIN, QUALIFIED_NAME, dbName);
                return (localEntity.get("owner") != null && localEntity.get("owner").equals(newEntity.get("owner")));
            }
        });

        //Its partial update and un-set fields are not updated
        Referenceable actualEntity = atlasClientV1.getEntity(DATABASE_TYPE_BUILTIN, QUALIFIED_NAME, dbName);
        assertEquals(actualEntity.get(DESCRIPTION), entity.get(DESCRIPTION));
    }

    @Test
    public void testUpdatePartialUpdatingQualifiedName() throws Exception {
        final Referenceable entity = new Referenceable(DATABASE_TYPE_BUILTIN);
        final String dbName = "db" + randomString();
        entity.set(NAME, dbName);
        entity.set(DESCRIPTION, randomString());
        entity.set(QUALIFIED_NAME, dbName);
        entity.set(CLUSTER_NAME, randomString());

        atlasClientV1.createEntity(entity);

        final Referenceable newEntity = new Referenceable(DATABASE_TYPE_BUILTIN);
        final String newName = "db" + randomString();
        newEntity.set(QUALIFIED_NAME, newName);

        sendHookMessage(
                new HookNotification.EntityPartialUpdateRequest(TEST_USER, DATABASE_TYPE_BUILTIN, QUALIFIED_NAME, dbName, newEntity));
        waitFor(MAX_WAIT_TIME, new Predicate() {
            @Override
            public boolean evaluate() throws Exception {
                JSONArray results = searchByDSL(String.format("%s where qualifiedName='%s'", DATABASE_TYPE_BUILTIN, newName));
                return results.length() == 1;
            }
        });

        //no entity with the old qualified name
        JSONArray results = searchByDSL(String.format("%s where qualifiedName='%s'", DATABASE_TYPE_BUILTIN, dbName));
        assertEquals(results.length(), 0);

    }

    @Test
    public void testDeleteByQualifiedName() throws Exception {
        Referenceable entity = new Referenceable(DATABASE_TYPE_BUILTIN);
        final String dbName = "db" + randomString();
        entity.set(NAME, dbName);
        entity.set(DESCRIPTION, randomString());
        entity.set(QUALIFIED_NAME, dbName);
        entity.set(CLUSTER_NAME, randomString());

        final String dbId = atlasClientV1.createEntity(entity).get(0);

        sendHookMessage(
            new HookNotification.EntityDeleteRequest(TEST_USER, DATABASE_TYPE_BUILTIN, QUALIFIED_NAME, dbName));
        waitFor(MAX_WAIT_TIME, new Predicate() {
            @Override
            public boolean evaluate() throws Exception {
                Referenceable getEntity = atlasClientV1.getEntity(dbId);
                return getEntity.getId().getState() == Id.EntityState.DELETED;
            }
        });
    }

    @Test
    public void testUpdateEntityFullUpdate() throws Exception {
        Referenceable entity = new Referenceable(DATABASE_TYPE_BUILTIN);
        final String dbName = "db" + randomString();
        entity.set(NAME, dbName);
        entity.set(DESCRIPTION, randomString());
        entity.set(QUALIFIED_NAME, dbName);
        entity.set(CLUSTER_NAME, randomString());

        atlasClientV1.createEntity(entity);

        final Referenceable newEntity = new Referenceable(DATABASE_TYPE_BUILTIN);
        newEntity.set(NAME, randomString());
        newEntity.set(DESCRIPTION, randomString());
        newEntity.set("owner", randomString());
        newEntity.set(QUALIFIED_NAME, dbName);
        newEntity.set(CLUSTER_NAME, randomString());

        //updating unique attribute
        sendHookMessage(new HookNotification.EntityUpdateRequest(TEST_USER, newEntity));
        waitFor(MAX_WAIT_TIME, new Predicate() {
            @Override
            public boolean evaluate() throws Exception {
                JSONArray results = searchByDSL(String.format("%s where qualifiedName='%s'", DATABASE_TYPE_BUILTIN, newEntity.get(QUALIFIED_NAME)));
                return results.length() == 1;
            }
        });

        Referenceable actualEntity = atlasClientV1.getEntity(DATABASE_TYPE_BUILTIN, QUALIFIED_NAME, dbName);
        assertEquals(actualEntity.get(DESCRIPTION), newEntity.get(DESCRIPTION));
        assertEquals(actualEntity.get("owner"), newEntity.get("owner"));
    }


}
