/*
 * 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.ignite.stream.mqtt;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.ignite.IgniteDataStreamer;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.stream.StreamAdapter;
import org.apache.ignite.stream.StreamMultipleTupleExtractor;
import org.apache.ignite.stream.StreamSingleTupleExtractor;

import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.StopStrategy;
import com.github.rholder.retry.WaitStrategies;
import com.github.rholder.retry.WaitStrategy;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttClientPersistence;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;

/**
 * Streamer that consumes from a MQTT topic and feeds key-value pairs into an {@link IgniteDataStreamer} instance,
 * using Eclipse Paho as an MQTT client.
 * <p>
 * You must also provide a {@link StreamSingleTupleExtractor} or a {@link StreamMultipleTupleExtractor} to extract
 * cache tuples out of the incoming message.
 * <p>
 * This Streamer has many features:
 *
 * <ul>
 *     <li>Subscribing to a single topic or multiple topics at once.</li>
 *     <li>Specifying the subscriber's QoS for a single topic or for multiple topics.</li>
 *     <li>Allows setting {@link MqttConnectOptions} to support features like last will testament, persistent
 *         sessions, etc.</li>
 *     <li>Specifying the client ID. A random one will be generated and maintained throughout reconnections if the user
 *         does not provide one.</li>
 *     <li>(Re-)Connection retries based on the <i>guava-retrying</i> library. Retry wait and retry stop policies
 *         can be configured.</li>
 *     <li>Blocking the start() method until connected for the first time.</li>
 * </ul>
 *
 * Note: features like durable subscriptions, last will testament, etc. can be configured via the
 * {@link #setConnectOptions(MqttConnectOptions)} setter.
 *
 * @see <a href="https://github.com/rholder/guava-retrying">guava-retrying library</a>
 */
public class MqttStreamer<K, V> extends StreamAdapter<MqttMessage, K, V> implements MqttCallback {
    /** Logger. */
    private IgniteLogger log;

    /** The MQTT client object for internal use. */
    private MqttClient client;

    /** The broker URL, set by the user. */
    private String brokerUrl;

    /** The topic to subscribe to, if a single topic. */
    private String topic;

    /** The quality of service to use for a single topic subscription (optional). */
    private Integer qualityOfService;

    /** The topics to subscribe to, if many. */
    private List<String> topics;

    /**
     * The qualities of service to use for multiple topic subscriptions. If specified, it must contain the same
     * number of elements as {@link #topics}.
     */
    private List<Integer> qualitiesOfService;

    /** The MQTT client ID (optional). */
    private String clientId;

    /** A configurable persistence mechanism. If not set, Paho will use its default. */
    private MqttClientPersistence persistence;

    /** The MQTT client connect options, where users can configured the last will and testament, durability, etc. */
    private MqttConnectOptions connectOptions;

    /** Quiesce timeout on disconnection. */
    private Integer disconnectQuiesceTimeout;

    /** Whether to disconnect forcibly or not. */
    private boolean disconnectForcibly;

    /** If disconnecting forcibly, the timeout. */
    private Integer disconnectForciblyTimeout;

    /**
     * The strategy to determine how long to wait between retry attempts. By default, this streamer uses a
     * Fibonacci-based strategy.
     */
    private WaitStrategy retryWaitStrategy = WaitStrategies.fibonacciWait();

    /** The strategy to determine when to stop retrying to (re-)connect. By default, we never stop. */
    private StopStrategy retryStopStrategy = StopStrategies.neverStop();

    /** The internal connection retrier object with a thread pool of size 1. */
    private MqttConnectionRetrier connectionRetrier;

    /** Whether to block the start() method until connected for the first time. */
    private boolean blockUntilConnected;

    /** State keeping. */
    private volatile boolean stopped = true;

    /** Cached log prefix for cache messages. */
    private String cachedLogValues;

    /**
     * Starts streamer.
     *
     * @throws IgniteException If failed.
     */
    public void start() throws IgniteException {
        if (!stopped)
            throw new IgniteException("Attempted to start an already started MQTT Streamer");

        // For simplicity, if these are null initialize to empty lists.
        topics = topics == null ? new ArrayList<String>() : topics;

        qualitiesOfService = qualitiesOfService == null ? new ArrayList<Integer>() : qualitiesOfService;

        try {
            Map<String, Object> logValues = new HashMap<>();

            // Parameter validations.
            A.notNull(getStreamer(), "streamer");
            A.notNull(getIgnite(), "ignite");
            A.ensure(!(getSingleTupleExtractor() == null && getMultipleTupleExtractor() == null),
                "tuple extractor missing");
            A.ensure(getSingleTupleExtractor() == null || getMultipleTupleExtractor() == null,
                "cannot provide both single and multiple tuple extractor");
            A.notNullOrEmpty(brokerUrl, "broker URL");

            // If the client ID is empty, generate one.
            if (clientId == null || clientId.length() == 0)
                clientId = MqttClient.generateClientId();

            // If we have both a single topic and a list of topics (but the list of topic is not of
            // size 1 and == topic, as this would be a case of re-initialization), fail.
            if (topic != null && topic.length() > 0 && !topics.isEmpty() &&
                topics.size() != 1 && !topics.get(0).equals(topic))
                throw new IllegalArgumentException("Cannot specify both a single topic and a list at the same time.");

            // Same as above but for QoS.
            if (qualityOfService != null && !qualitiesOfService.isEmpty() && qualitiesOfService.size() != 1 &&
                !qualitiesOfService.get(0).equals(qualityOfService))
                throw new IllegalArgumentException("Cannot specify both a single QoS and a list at the same time.");

            // Paho API requires disconnect timeout if providing a quiesce timeout and disconnecting forcibly.
            if (disconnectForcibly && disconnectQuiesceTimeout != null)
                A.notNull(disconnectForciblyTimeout, "disconnect timeout cannot be null when disconnecting forcibly " +
                    "with quiesce");

            // If we have multiple topics.
            if (!topics.isEmpty()) {
                for (String t : topics)
                    A.notNullOrEmpty(t, "topic in list of topics");

                A.ensure(qualitiesOfService.isEmpty() || qualitiesOfService.size() == topics.size(),
                    "qualities of service must be either empty or have the same size as topics list");

                logValues.put("topics", topics);
            }
            else {
                // Just the single topic.
                topics.add(topic);

                if (qualityOfService != null)
                    qualitiesOfService.add(qualityOfService);

                logValues.put("topic", topic);
            }

            // Finish building log values.
            logValues.put("brokerUrl", brokerUrl);
            logValues.put("clientId", clientId);

            // Cache log values.
            cachedLogValues = "[" + Joiner.on(", ").withKeyValueSeparator("=").join(logValues) + "]";

            // Create logger.
            log = getIgnite().log();

            // Create the MQTT client.
            if (persistence == null)
                client = new MqttClient(brokerUrl, clientId);
            else
                client = new MqttClient(brokerUrl, clientId, persistence);

            // Set this as a callback.
            client.setCallback(this);

            // Set stopped to false, as the connection will start async.
            stopped = false;

            // Build retrier.
            Retryer<Void> retrier = RetryerBuilder.<Void>newBuilder()
                .retryIfResult(new Predicate<Void>() {
                    @Override public boolean apply(Void v) {
                        return !client.isConnected() && !stopped;
                    }
                })
                .retryIfException().retryIfRuntimeException()
                .withWaitStrategy(retryWaitStrategy)
                .withStopStrategy(retryStopStrategy)
                .build();

            // Create the connection retrier.
            connectionRetrier = new MqttConnectionRetrier(retrier);

            if (log.isInfoEnabled())
                log.info("Starting MQTT Streamer " + cachedLogValues);

            // Connect.
            connectionRetrier.connect();
        }
        catch (Exception e) {
            throw new IgniteException("Failed to initialize MQTT Streamer.", e);
        }
    }

    /**
     * Stops streamer.
     *
     * @throws IgniteException If failed.
     */
    public void stop() throws IgniteException {
        if (stopped)
            throw new IgniteException("Failed to stop MQTT Streamer (already stopped).");

        // Stop the retrier.
        connectionRetrier.stop();

        try {
            if (disconnectForcibly) {
                if (disconnectQuiesceTimeout == null && disconnectForciblyTimeout == null)
                    client.disconnectForcibly();

                else if (disconnectForciblyTimeout != null && disconnectQuiesceTimeout == null)
                    client.disconnectForcibly(disconnectForciblyTimeout);

                else
                    client.disconnectForcibly(disconnectQuiesceTimeout, disconnectForciblyTimeout);
            }
            else {
                if (disconnectQuiesceTimeout == null)
                    client.disconnect();

                else
                    client.disconnect(disconnectQuiesceTimeout);
            }

            client.close();

            stopped = true;
        }
        catch (Exception e) {
            throw new IgniteException("Failed to stop Exception while stopping MQTT Streamer.", e);
        }
    }

    // -------------------------------
    //  MQTT Client callback methods
    // -------------------------------

    /**
     * Implements the {@link MqttCallback#connectionLost(Throwable)} callback method for the MQTT client to inform the
     * streamer that the connection has been lost.
     *
     * {@inheritDoc}
     */
    @Override public void connectionLost(Throwable throwable) {
        // If we have been stopped, we do not try to establish the connection again.
        if (stopped)
            return;

        log.warning(String.format("MQTT Connection to broker was lost [brokerUrl=%s, type=%s, err=%s]", brokerUrl,
            throwable.getClass(), throwable.getMessage()));

        connectionRetrier.connect();
    }

    /**
     * Implements the {@link MqttCallback#messageArrived(String, MqttMessage)} to receive an MQTT message.
     *
     * {@inheritDoc}
     */
    @Override public void messageArrived(String topic, MqttMessage message) throws Exception {
        if (getMultipleTupleExtractor() != null) {
            Map<K, V> entries = getMultipleTupleExtractor().extract(message);

            if (log.isTraceEnabled())
                log.trace("Adding cache entries: " + entries);

            getStreamer().addData(entries);
        }
        else {
            Map.Entry<K, V> entry = getSingleTupleExtractor().extract(message);

            if (log.isTraceEnabled())
                log.trace("Adding cache entry: " + entry);

            getStreamer().addData(entry);
        }
    }

    /**
     * Empty implementation of {@link MqttCallback#deliveryComplete(IMqttDeliveryToken)}.
     *
     * Not required by the streamer as it doesn't produce messages.
     *
     * {@inheritDoc}
     */
    @Override public void deliveryComplete(IMqttDeliveryToken token) {
        // ignore, as we don't send messages
    }

    // -------------------------------
    //  Getters and setters
    // -------------------------------

    /**
     * Sets the broker URL (compulsory).
     *
     * @param brokerUrl The Broker URL (compulsory).
     */
    public void setBrokerUrl(String brokerUrl) {
        this.brokerUrl = brokerUrl;
    }

    /**
     * Gets the broker URL.
     *
     * @return The Broker URL.
     */
    public String getBrokerUrl() {
        return brokerUrl;
    }

    /**
     * Sets the topic to subscribe to, if a single topic.
     *
     * @param topic The topic to subscribe to.
     */
    public void setTopic(String topic) {
        this.topic = topic;
    }

    /**
     * Gets the subscribed topic.
     *
     * @return The subscribed topic.
     */
    public String getTopic() {
        return topic;
    }

    /**
     * Sets the quality of service to use for a single topic subscription (optional).
     *
     * @param qualityOfService The quality of service.
     */
    public void setQualityOfService(Integer qualityOfService) {
        this.qualityOfService = qualityOfService;
    }

    /**
     * Gets the quality of service set by the user for a single topic consumption.
     *
     * @return The quality of service.
     */
    public Integer getQualityOfService() {
        return qualityOfService;
    }

    /**
     * Sets the topics to subscribe to, if many.
     *
     * @param topics The topics.
     */
    public void setTopics(List<String> topics) {
        this.topics = topics;
    }

    /**
     * Gets the topics subscribed to.
     *
     * @return The topics subscribed to.
     */
    public List<String> getTopics() {
        return topics;
    }

    /**
     * Sets the qualities of service to use for multiple topic subscriptions. If specified, the list must contain the
     * same number of elements as {@link #topics}.
     *
     * @param qualitiesOfService The qualities of service.
     */
    public void setQualitiesOfService(List<Integer> qualitiesOfService) {
        this.qualitiesOfService = qualitiesOfService;
    }

    /**
     * Gets the qualities of service for multiple topics.
     *
     * @return The qualities of service.
     */
    public List<Integer> getQualitiesOfService() {
        return qualitiesOfService;
    }

    /**
     * Sets the MQTT client ID (optional). If one is not provided, the streamer will generate one and will maintain
     * it througout any reconnection attempts.
     *
     * @param clientId The client ID.
     */
    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    /**
     * Gets the client ID, either the one set by the user or the automatically generated one.
     *
     * @return The client ID.
     */
    public String getClientId() {
        return clientId;
    }

    /**
     * Gets the currently set persistence mechanism.
     *
     * @return The persistence mechanism.
     */
    public MqttClientPersistence getPersistence() {
        return persistence;
    }

    /**
     * Sets the persistence mechanism. If not set, Paho will use its default.
     *
     * @param persistence A configurable persistence mechanism.
     */
    public void setPersistence(MqttClientPersistence persistence) {
        this.persistence = persistence;
    }

    /**
     * Gets the currently used MQTT client connect options.
     *
     * @return The MQTT client connect options.
     */
    public MqttConnectOptions getConnectOptions() {
        return connectOptions;
    }

    /**
     * Sets the MQTT client connect options, where users can configured the last will and testament, durability, etc.
     *
     * @param connectOptions The MQTT client connect options.
     */
    public void setConnectOptions(MqttConnectOptions connectOptions) {
        this.connectOptions = connectOptions;
    }

    /**
     * Sets whether to disconnect forcibly or not when shutting down. By default, it's {@code false}.
     *
     * @param disconnectForcibly Whether to disconnect forcibly or not. By default, it's {@code false}.
     */
    public void setDisconnectForcibly(boolean disconnectForcibly) {
        this.disconnectForcibly = disconnectForcibly;
    }

    /**
     * Gets whether this MQTT client will disconnect forcibly when shutting down.
     *
     * @return Whether to disconnect forcibly or not.
     */
    public boolean isDisconnectForcibly() {
        return disconnectForcibly;
    }

    /**
     * Sets the quiesce timeout on disconnection. If not provided, this streamer won't use any.
     *
     * @param disconnectQuiesceTimeout The disconnect quiesce timeout.
     */
    public void setDisconnectQuiesceTimeout(Integer disconnectQuiesceTimeout) {
        this.disconnectQuiesceTimeout = disconnectQuiesceTimeout;
    }

    /**
     * Gets the disconnect quiesce timeout.
     *
     * @return The disconnect quiesce timeout.
     */
    public Integer getDisconnectQuiesceTimeout() {
        return disconnectQuiesceTimeout;
    }

    /**
     * Sets the timeout if disconnecting forcibly. Compulsory in that case.
     *
     * @param disconnectForciblyTimeout The disconnect forcibly timeout.
     */
    public void setDisconnectForciblyTimeout(Integer disconnectForciblyTimeout) {
        this.disconnectForciblyTimeout = disconnectForciblyTimeout;
    }

    /**
     * Gets the timeout if disconnecting forcibly.
     *
     * @return Timeout.
     */
    public Integer getDisconnectForciblyTimeout() {
        return disconnectForciblyTimeout;
    }

    /**
     * Sets the strategy to determine how long to wait between retry attempts. By default, this streamer uses a
     * Fibonacci-based strategy.
     *
     * @param retryWaitStrategy The retry wait strategy.
     */
    public void setRetryWaitStrategy(WaitStrategy retryWaitStrategy) {
        this.retryWaitStrategy = retryWaitStrategy;
    }

    /**
     * Gets the retry wait strategy.
     *
     * @return The retry wait strategy.
     */
    public WaitStrategy getRetryWaitStrategy() {
        return retryWaitStrategy;
    }

    /**
     * Sets the strategy to determine when to stop retrying to (re-)connect. By default, we never stop.
     *
     * @param retryStopStrategy The retry stop strategy.
     */
    public void setRetryStopStrategy(StopStrategy retryStopStrategy) {
        this.retryStopStrategy = retryStopStrategy;
    }

    /**
     * Gets the retry stop strategy.
     *
     * @return The retry stop strategy.
     */
    public StopStrategy getRetryStopStrategy() {
        return retryStopStrategy;
    }

    /**
     * Sets whether to block the start() method until connected for the first time. By default, it's {@code false}.
     *
     * @param blockUntilConnected Whether to block or not.
     */
    public void setBlockUntilConnected(boolean blockUntilConnected) {
        this.blockUntilConnected = blockUntilConnected;
    }

    /**
     * Gets whether to block the start() method until connected for the first time. By default, it's {@code false}.
     *
     * @return {@code true} if should connect synchronously in start.
     */
    public boolean isBlockUntilConnected() {
        return blockUntilConnected;
    }

    /**
     * Returns whether this streamer is stopped.
     *
     * @return {@code true} if stopped; {@code false} if not.
     */
    public boolean isStopped() {
        return stopped;
    }

    /**
     * Returns whether this streamer is connected by delegating to the underlying {@link MqttClient#isConnected()}
     *
     * @return {@code true} if connected; {@code false} if not.
     * @see MqttClient#isConnected()
     */
    public boolean isConnected() {
        return client.isConnected();
    }

    /**
     * A utility class to help us with (re-)connecting to the MQTT broker. It uses a single-threaded executor to perform
     * the (re-)connections.
     */
    private class MqttConnectionRetrier {
        /** The guava-retrying retrier object. */
        private final Retryer<Void> retrier;

        /** Single-threaded pool. */
        private final ExecutorService exec = Executors.newSingleThreadExecutor();

        /**
         * Constructor.
         *
         * @param retrier The retryier object.
         */
        public MqttConnectionRetrier(Retryer<Void> retrier) {
            this.retrier = retrier;
        }

        /**
         * Method called by the streamer to ask us to (re-)connect.
         */
        public void connect() {
            Callable<Void> callable = retrier.wrap(new Callable<Void>() {
                @Override public Void call() throws Exception {
                    // If we're already connected, return immediately.
                    if (client.isConnected())
                        return null;

                    if (stopped)
                        return null;

                    // Connect to broker.
                    if (connectOptions == null)
                        client.connect();
                    else
                        client.connect(connectOptions);

                    // Always use the multiple topics variant of the mqtt client; even if the user specified a single
                    // topic and/or QoS, the initialization code would have placed it inside the 1..n structures.
                    if (qualitiesOfService.isEmpty())
                        client.subscribe(topics.toArray(new String[0]));

                    else {
                        int[] qoses = new int[qualitiesOfService.size()];

                        for (int i = 0; i < qualitiesOfService.size(); i++)
                            qoses[i] = qualitiesOfService.get(i);

                        client.subscribe(topics.toArray(new String[0]), qoses);
                    }

                    if (log.isInfoEnabled())
                        log.info("MQTT Streamer (re-)connected and subscribed " + cachedLogValues);

                    return null;
                }
            });

            Future<Void> result = exec.submit(callable);

            if (blockUntilConnected) {
                try {
                    result.get();
                }
                catch (Throwable e) {
                    throw new RuntimeException(e);
                }
            }
        }

        /**
         * Stops this connection utility class by shutting down the thread pool.
         */
        public void stop() {
            exec.shutdownNow();
        }
    }
}
