/*
 * 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.sling.distribution.journal.kafka;

import java.io.Closeable;
import java.io.IOException;

import org.apache.sling.distribution.journal.ExceptionEventSender;
import org.apache.sling.distribution.journal.MessageHandler;
import org.apache.sling.distribution.journal.MessageInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.errors.WakeupException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.sling.distribution.journal.RunnableUtil.startBackgroundThread;
import static java.lang.String.format;
import static java.time.Duration.ofHours;
import static java.util.Objects.requireNonNull;

public class KafkaJsonMessagePoller<T> implements Closeable {

    private static final Logger LOG = LoggerFactory.getLogger(KafkaJsonMessagePoller.class);

    private volatile boolean running = true;

    private final KafkaConsumer<String, String> consumer;

    private final MessageHandler<T> handler;

    private final ObjectReader reader;

    private final ExceptionEventSender eventSender;

    public KafkaJsonMessagePoller(KafkaConsumer<String, String> consumer, ExceptionEventSender eventSender, MessageHandler<T> handler, Class<T> clazz) {
        this.consumer = requireNonNull(consumer);
        this.eventSender = requireNonNull(eventSender);
        this.handler = requireNonNull(handler);
        ObjectMapper mapper = new ObjectMapper();
        reader = mapper.readerFor(requireNonNull(clazz));
        startBackgroundThread(this::run, format("Message Json Poller for handler %s", handler));
    }

    @Override
    public void close() throws IOException {
        LOG.info("Shutdown JSON poller for handler {}", handler);
        running = false;
        consumer.wakeup();
    }

    public void run() {
        LOG.info("Start JSON poller for handler {}", handler);
        while(running) {
            try {
                consumer.poll(ofHours(1))
                    .forEach(this::handleRecord);
            } catch (WakeupException e) {
                LOG.debug("Waked up while stopping {}", e.getMessage(), e);
                running = false;
            } catch(Exception e) {
                eventSender.send(e);
                LOG.error("Exception during recieve: {}", e.getMessage(), e);
                sleepAfterError();
                // Continue as KafkaConsumer should handle the error transparently
            }
        }
        consumer.close();
        LOG.info("Stop JSON poller for handler {}", handler);
    }
    
    private void sleepAfterError() {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e1) {
            Thread.currentThread().interrupt();
        }
    }

    private void handleRecord(ConsumerRecord<String, String> record) {
        MessageInfo info = new KafkaMessageInfo(record);
        String payload = record.value();
        try {
            T message = reader.readValue(payload);
            handler.handle(info, message);
        } catch (IOException e) {
            eventSender.send(e);
            LOG.error("Failed to parse payload {}", payload);
        }
    }
}
