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

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.apache.atlas.AtlasConstants;
import org.apache.atlas.falcon.bridge.FalconBridge;
import org.apache.atlas.falcon.event.FalconEvent;
import org.apache.atlas.falcon.publisher.FalconEventPublisher;
import org.apache.atlas.hook.AtlasHook;
import org.apache.atlas.notification.NotificationInterface;
import org.apache.atlas.notification.NotificationModule;
import org.apache.atlas.notification.hook.HookNotification;
import org.apache.atlas.typesystem.Referenceable;
import org.apache.falcon.entity.store.ConfigurationStore;
import org.apache.falcon.entity.v0.feed.Feed;
import org.apache.falcon.entity.v0.process.Process;
import org.apache.hadoop.util.ShutdownHookManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Falcon hook sends lineage information to the Atlas Service.
 */
public class FalconHook extends AtlasHook implements FalconEventPublisher {
    private static final Logger LOG = LoggerFactory.getLogger(FalconHook.class);

    public static final String CONF_PREFIX = "atlas.hook.falcon.";
    private static final String MIN_THREADS = CONF_PREFIX + "minThreads";
    private static final String MAX_THREADS = CONF_PREFIX + "maxThreads";
    private static final String KEEP_ALIVE_TIME = CONF_PREFIX + "keepAliveTime";
    public static final String QUEUE_SIZE = CONF_PREFIX + "queueSize";
    public static final String CONF_SYNC = CONF_PREFIX + "synchronous";

    public static final String HOOK_NUM_RETRIES = CONF_PREFIX + "numRetries";

    // wait time determines how long we wait before we exit the jvm on
    // shutdown. Pending requests after that will not be sent.
    private static final int WAIT_TIME = 3;
    private static ExecutorService executor;

    private static final int minThreadsDefault = 5;
    private static final int maxThreadsDefault = 5;
    private static final long keepAliveTimeDefault = 10;
    private static final int queueSizeDefault = 10000;

    private static boolean sync;

    private static ConfigurationStore STORE;

    private enum Operation {
        ADD,
        UPDATE
    }

    static {
        try {
            // initialize the async facility to process hook calls. We don't
            // want to do this inline since it adds plenty of overhead for the query.
            int minThreads = atlasProperties.getInt(MIN_THREADS, minThreadsDefault);
            int maxThreads = atlasProperties.getInt(MAX_THREADS, maxThreadsDefault);
            long keepAliveTime = atlasProperties.getLong(KEEP_ALIVE_TIME, keepAliveTimeDefault);
            int queueSize = atlasProperties.getInt(QUEUE_SIZE, queueSizeDefault);
            sync = atlasProperties.getBoolean(CONF_SYNC, false);

            executor = new ThreadPoolExecutor(minThreads, maxThreads, keepAliveTime, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>(queueSize),
                    new ThreadFactoryBuilder().setNameFormat("Atlas Logger %d").build());

            ShutdownHookManager.get().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    try {
                        LOG.info("==> Shutdown of Atlas Falcon Hook");

                        executor.shutdown();
                        executor.awaitTermination(WAIT_TIME, TimeUnit.SECONDS);
                        executor = null;
                    } catch (InterruptedException ie) {
                        LOG.info("Interrupt received in shutdown.");
                    } finally {
                        LOG.info("<== Shutdown of Atlas Falcon Hook");
                    }
                    // shutdown client
                }
            }, AtlasConstants.ATLAS_SHUTDOWN_HOOK_PRIORITY);

            STORE = ConfigurationStore.get();

            Injector injector = Guice.createInjector(new NotificationModule());
            notifInterface = injector.getInstance(NotificationInterface.class);

        } catch (Exception e) {
            LOG.error("Caught exception initializing the falcon hook.", e);
        }


        LOG.info("Created Atlas Hook for Falcon");
    }

    @Override
    public void publish(final Data data) throws Exception {
        final FalconEvent event = data.getEvent();
        try {
            if (sync) {
                fireAndForget(event);
            } else {
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            fireAndForget(event);
                        } catch (Throwable e) {
                            LOG.info("Atlas hook failed", e);
                        }
                    }
                });
            }
        } catch (Throwable t) {
            LOG.warn("Error in processing data {}", data, t);
        }
    }

    @Override
    protected String getNumberOfRetriesPropertyKey() {
        return HOOK_NUM_RETRIES;
    }

    private void fireAndForget(FalconEvent event) throws Exception {
        LOG.info("Entered Atlas hook for Falcon hook operation {}", event.getOperation());
        List<HookNotification.HookNotificationMessage> messages = new ArrayList<>();

        Operation op = getOperation(event.getOperation());
        String user = getUser(event.getUser());
        LOG.info("fireAndForget user:{}", user);
        switch (op) {
        case ADD:
            messages.add(new HookNotification.EntityCreateRequest(user, createEntities(event, user)));
            break;

        }
        notifyEntities(messages);
    }

    private List<Referenceable> createEntities(FalconEvent event, String user) throws Exception {
        List<Referenceable> entities = new ArrayList<>();

        switch (event.getOperation()) {
        case ADD_CLUSTER:
            entities.add(FalconBridge
                    .createClusterEntity((org.apache.falcon.entity.v0.cluster.Cluster) event.getEntity()));
            break;

        case ADD_PROCESS:
            entities.addAll(FalconBridge.createProcessEntity((Process) event.getEntity(), STORE));
            break;

        case ADD_FEED:
            entities.addAll(FalconBridge.createFeedCreationEntity((Feed) event.getEntity(), STORE));
            break;

        case UPDATE_CLUSTER:
        case UPDATE_FEED:
        case UPDATE_PROCESS:
        default:
            LOG.info("Falcon operation {} is not valid or supported", event.getOperation());
        }

        return entities;
    }

    private static Operation getOperation(final FalconEvent.OPERATION op) throws Exception {
        switch (op) {
        case ADD_CLUSTER:
        case ADD_FEED:
        case ADD_PROCESS:
            return Operation.ADD;

        case UPDATE_CLUSTER:
        case UPDATE_FEED:
        case UPDATE_PROCESS:
            return Operation.UPDATE;

        default:
            throw new Exception("Falcon operation " + op + " is not valid or supported");
        }
    }
}

