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

import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.distribution.DistributionRequestType;
import org.apache.sling.distribution.common.DistributionException;
import org.apache.sling.distribution.common.RecoverableDistributionException;
import org.apache.sling.distribution.component.impl.DistributionComponentKind;
import org.apache.sling.distribution.event.DistributionEventTopics;
import org.apache.sling.distribution.event.impl.DistributionEventFactory;
import org.apache.sling.distribution.log.impl.DefaultDistributionLog;
import org.apache.sling.distribution.packaging.DistributionPackage;
import org.apache.sling.distribution.packaging.impl.DistributionPackageExporter;
import org.apache.sling.distribution.packaging.impl.DistributionPackageImporter;
import org.apache.sling.distribution.packaging.impl.DistributionPackageUtils;
import org.apache.sling.distribution.queue.DistributionQueueEntry;
import org.apache.sling.distribution.queue.DistributionQueueItem;
import org.apache.sling.distribution.queue.DistributionQueueItemStatus;
import org.apache.sling.distribution.queue.impl.DistributionQueueProcessor;
import org.apache.sling.distribution.queue.impl.DistributionQueueProvider;
import org.apache.sling.distribution.queue.impl.DistributionQueueDispatchingStrategy;
import org.apache.sling.distribution.util.impl.DistributionUtils;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A processor of agent queue entries, each entry's underlying package is fetched and passed to the
 * {@link DistributionPackageImporter} for import.
 * If item can be delivered it can be removed from the queue, if it cannot be delivered because of a {@link RecoverableDistributionException}
 * like a connection issue the item will stay in the queue, for other types of errors the item will be moved to the
 * current queue "error queue" if that exists.
 */
class SimpleDistributionAgentQueueProcessor implements DistributionQueueProcessor {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private final DistributionPackageExporter distributionPackageExporter;
    private final DistributionPackageImporter distributionPackageImporter;
    private final int retryAttempts;
    private final DistributionQueueDispatchingStrategy errorQueueStrategy;
    private final DefaultDistributionLog distributionLog;
    private final DistributionQueueProvider queueProvider;
    private final DistributionEventFactory distributionEventFactory;
    private final SimpleDistributionAgentAuthenticationInfo authenticationInfo;
    private final String agentName;

    public SimpleDistributionAgentQueueProcessor(DistributionPackageExporter distributionPackageExporter,
                                                 DistributionPackageImporter distributionPackageImporter, int retryAttempts,
                                                 DistributionQueueDispatchingStrategy errorQueueStrategy, DefaultDistributionLog log,
                                                 DistributionQueueProvider queueProvider, DistributionEventFactory distributionEventFactory,
                                                 SimpleDistributionAgentAuthenticationInfo authenticationInfo, String agentName) {
        this.distributionPackageExporter = distributionPackageExporter;

        this.distributionPackageImporter = distributionPackageImporter;
        this.retryAttempts = retryAttempts;
        this.errorQueueStrategy = errorQueueStrategy;
        this.distributionLog = log;
        this.queueProvider = queueProvider;
        this.distributionEventFactory = distributionEventFactory;
        this.authenticationInfo = authenticationInfo;
        this.agentName = agentName;
    }

    @Override
    public boolean process(@NotNull String queueName, @NotNull DistributionQueueEntry queueEntry) {
        DistributionQueueItem queueItem = queueEntry.getItem();

        try {
            final long startTime = System.currentTimeMillis();

            distributionLog.debug("[{}] ITEM-PROCESS processing item={}", queueName, queueItem);

            boolean success = processQueueItem(queueName, queueEntry);

            final long endTime = System.currentTimeMillis();

            distributionLog.debug("[{}] ITEM-PROCESSED item={}, status={}, processingTime={}ms", queueName, queueItem, success, endTime - startTime);

            return success;

        } catch (Throwable t) {
            distributionLog.error("[{}] ITEM-FAIL item={}", queueName, queueItem, t);
            return false;
        }
    }

    private boolean processQueueItem(String queueName, DistributionQueueEntry queueEntry) throws DistributionException {
        boolean removeItemFromQueue = false;
        ResourceResolver agentResourceResolver = null;
        DistributionPackage distributionPackage = null;
        DistributionQueueItem queueItem = queueEntry.getItem();
        DistributionQueueItemStatus queueItemStatus = queueEntry.getStatus();
        try {

            int processingAttempt = queueItemStatus.getAttempts();
            if (processingAttempt > 0) {
                // since there is a retry, it is possible that the same error is observed again
                // we should add a linear backoff using random delay before re-attempting to distribute the same item.
                addRandomDelay(queueItemStatus.getAttempts());
            }

            String callingUser = queueItem.get(DistributionPackageUtils.PACKAGE_INFO_PROPERTY_REQUEST_USER, String.class);
            String requestId = queueItem.get(DistributionPackageUtils.PACKAGE_INFO_PROPERTY_REQUEST_ID, String.class);
            Long globalStartTime = queueItem.get(DistributionPackageUtils.PACKAGE_INFO_PROPERTY_REQUEST_START_TIME, Long.class);

            agentResourceResolver = DistributionUtils.getResourceResolver(callingUser, authenticationInfo.getAgentService(),
                    authenticationInfo.getSlingRepository(), authenticationInfo.getSubServiceName(),
                    authenticationInfo.getResourceResolverFactory());

            final long startTime = System.currentTimeMillis();

            distributionPackage = distributionPackageExporter.getPackage(agentResourceResolver, queueItem.getPackageId());

            if (distributionPackage != null) {
                final long packageSize = distributionPackage.getSize();
                DistributionPackageUtils.mergeQueueEntry(distributionPackage.getInfo(), queueEntry);

                final DistributionRequestType requestType = distributionPackage.getInfo().getRequestType();
                final String[] paths = distributionPackage.getInfo().getPaths();

                try {
                    // import package
                    distributionPackageImporter.importPackage(agentResourceResolver, distributionPackage);

                    // generated event
                    distributionEventFactory.generatePackageEvent(DistributionEventTopics.AGENT_PACKAGE_DISTRIBUTED,
                            DistributionComponentKind.AGENT, agentName, distributionPackage.getInfo());

                    removeItemFromQueue = true;
                    final long endTime = System.currentTimeMillis();

                    distributionLog.info("[{}] PACKAGE-DELIVERED {}: {} item={}, paths={}, importTime={}ms, execTime={}ms, size={}B", queueName, requestId,
                            requestType, queueEntry.getItem().getPackageId(), paths,
                            endTime - startTime, endTime - globalStartTime,
                            packageSize);
                } catch (RecoverableDistributionException e) {
                    distributionLog.warn("[{}] PACKAGE-FAIL {}: could not deliver {}, {}", queueName, requestId, distributionPackage.getId(), e.getMessage());
                    distributionLog.debug("could not deliver package {}", distributionPackage.getId(), e);
                } catch (Throwable e) {
                    distributionLog.error("[{}] PACKAGE-FAIL {}: could not deliver package {} {}", queueName, requestId, distributionPackage.getId(), e.getMessage(), e);
                    if (errorQueueStrategy != null && queueItemStatus.getAttempts() > retryAttempts) {
                        removeItemFromQueue = reEnqueuePackage(distributionPackage);
                        distributionEventFactory.generatePackageEvent(DistributionEventTopics.AGENT_PACKAGE_DROPPED,
                                DistributionComponentKind.AGENT, agentName, distributionPackage.getInfo());
                        distributionLog.info("[{}] PACKAGE-QUEUED {}: distribution package {} was enqueued to an error queue", queueName, requestId, distributionPackage.getId());
                    }
                }
            } else {
                removeItemFromQueue = true; // return success if package does not exist in order to clear the queue.
                distributionLog.error("distribution package with id {} does not exist. the package will be skipped.", queueItem.getPackageId());
            }
        } finally {
            if (removeItemFromQueue) {
                DistributionPackageUtils.releaseOrDelete(distributionPackage, queueName);
            } else {
                DistributionPackageUtils.closeSafely(distributionPackage);
            }
            DistributionUtils.ungetResourceResolver(agentResourceResolver);
        }

        // return true if item should be removed from queue
        return removeItemFromQueue;
    }

    private void addRandomDelay(int retryAttempts){
        int min = 1;
        int max = Math.min(retryAttempts, 30);
        int random = (int)(Math.random() *  (max - min + 1) + min);
        try {
            Thread.sleep(random * 1000);
        } catch (InterruptedException ign) {
            // eat this exception
            // If there is an exception in Thread.sleep(), we will retry to distribute queueItem immediately.
        }
    }

    private boolean reEnqueuePackage(DistributionPackage distributionPackage) {

        if (errorQueueStrategy == null) {
            return false;
        }

        try {
            errorQueueStrategy.add(distributionPackage, queueProvider);
            log.warn("package {} moved to error queue", distributionPackage.getId());
        } catch (DistributionException e) {
            distributionLog.error("could not reenqueue package {}", distributionPackage.getId(), e);
            return false;
        }

        return true;
    }

}
