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

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.commons.io.IOUtils;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.distribution.DistributionRequest;
import org.apache.sling.distribution.DistributionRequestType;
import org.apache.sling.distribution.common.DistributionException;
import org.apache.sling.distribution.packaging.DistributionPackage;
import org.apache.sling.distribution.packaging.DistributionPackageBuilder;
import org.apache.sling.distribution.packaging.DistributionPackageInfo;
import org.apache.sling.distribution.serialization.impl.vlt.VltUtils;
import org.apache.sling.distribution.util.DistributionJcrUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * base abstract implementation of a JCR based {@link DistributionPackageBuilder}
 */
public abstract class AbstractDistributionPackageBuilder implements DistributionPackageBuilder {

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

    private final String type;

    AbstractDistributionPackageBuilder(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    @NotNull
    public DistributionPackage createPackage(@NotNull ResourceResolver resourceResolver, @NotNull DistributionRequest request)
            throws DistributionException {
        DistributionPackage distributionPackage;

        if (!VltUtils.isSupported(request)) {
            throw new DistributionException("unsupported request " + request);
        }

        if (DistributionRequestType.ADD.equals(request.getRequestType())) {
            distributionPackage = createPackageForAdd(resourceResolver, request);
        } else if (DistributionRequestType.DELETE.equals(request.getRequestType())) {
            distributionPackage = new SimpleDistributionPackage(request, type);
        } else if (DistributionRequestType.PULL.equals(request.getRequestType())) {
            distributionPackage = new SimpleDistributionPackage(request, type);
        } else if (DistributionRequestType.TEST.equals(request.getRequestType())) {
            distributionPackage = new SimpleDistributionPackage(request, type);
        } else {
            throw new DistributionException("unknown action type " + request.getRequestType());
        }

        DistributionPackageUtils.fillInfo(distributionPackage.getInfo(), request);

        return distributionPackage;
    }

    @NotNull
    public DistributionPackage readPackage(@NotNull ResourceResolver resourceResolver, @NotNull InputStream stream) throws DistributionException {

        if (!stream.markSupported()) {
            stream = new BufferedInputStream(stream);
        }
        Map<String, Object> headerInfo = new HashMap<String, Object>();
        DistributionPackageUtils.readInfo(stream, headerInfo);

        try {
            stream.reset();
        } catch (IOException e) {
            // do nothing
        }

        DistributionPackage distributionPackage = SimpleDistributionPackage.fromStream(stream, type);

        try {
            stream.reset();
        } catch (IOException e) {
            // do nothing
        }

        // not a simple package
        if (distributionPackage == null) {
            distributionPackage = readPackageInternal(resourceResolver, stream);
        }

        distributionPackage.getInfo().putAll(headerInfo);
        return distributionPackage;
    }

    public boolean installPackage(@NotNull ResourceResolver resourceResolver, @NotNull DistributionPackage distributionPackage) throws DistributionException {

        DistributionRequestType actionType = distributionPackage.getInfo().getRequestType();

        if (!type.equals(distributionPackage.getType())) {
            throw new DistributionException("not supported package type" + distributionPackage.getType());
        }

        boolean installed = false;
        if (DistributionRequestType.DELETE.equals(actionType)) {
            installed = installDeletePackage(resourceResolver, distributionPackage);
        } else if (DistributionRequestType.TEST.equals(actionType)) {
            // do nothing for test packages
            installed = true;
        } else if (DistributionRequestType.ADD.equals(actionType)) {
            installed = installAddPackage(resourceResolver, distributionPackage);
        }

        return installed;
    }

    @NotNull
    @Override
    public DistributionPackageInfo installPackage(@NotNull ResourceResolver resourceResolver, @NotNull InputStream stream) throws DistributionException {
        if (!stream.markSupported()) {
            stream = new BufferedInputStream(stream);
        }
        DistributionPackageInfo packageInfo = new DistributionPackageInfo(type);

        DistributionPackageUtils.readInfo(stream, packageInfo);

        DistributionPackage distributionPackage = SimpleDistributionPackage.fromStream(stream, type);

        boolean installed;
        // not a simple package
        if (distributionPackage == null) {
            installed = installPackageInternal(resourceResolver, stream);
        } else {
            installed = installPackage(resourceResolver, distributionPackage);
            packageInfo.putAll(distributionPackage.getInfo());
        }

        if (installed) {
            return packageInfo;
        } else {
            throw new DistributionException("could not install package from stream");
        }
    }

    private boolean installDeletePackage(@NotNull ResourceResolver resourceResolver, @Nullable DistributionPackage distributionPackage) throws DistributionException {
        Session session = null;
        try {
            if (distributionPackage != null) {
                session = getSession(resourceResolver);
                for (String path : distributionPackage.getInfo().getPaths()) {
                    if (session.itemExists(path)) {
                        session.removeItem(path);
                    }
                }
                return true;
            }
        } catch (Exception e) {
            throw new DistributionException(e);
        } finally {
            ungetSession(session);
        }

        return false;
    }


    private boolean installAddPackage(@NotNull ResourceResolver resourceResolver, @NotNull DistributionPackage distributionPackage)
            throws DistributionException {
        InputStream inputStream = null;
        try {
            inputStream = distributionPackage.createInputStream();
            return installPackageInternal(resourceResolver, inputStream);
        } catch (IOException e) {
            throw new DistributionException(e);
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    @Nullable
    public DistributionPackage getPackage(@NotNull ResourceResolver resourceResolver, @NotNull String id) {
        DistributionPackage distributionPackage = SimpleDistributionPackage.fromIdString(id, type);

        // not a simple package
        if (distributionPackage == null) {
            if (id.startsWith("reference")) {
                String localId = id.substring("reference-".length());
                distributionPackage = new ReferencePackage(getPackageInternal(resourceResolver, localId));
            } else {
                distributionPackage = getPackageInternal(resourceResolver, id);
            }

        }
        return distributionPackage;
    }

    private Session getSession(ResourceResolver resourceResolver) throws RepositoryException {
        Session session = resourceResolver.adaptTo(Session.class);
        if (session != null) {
            // this is needed in order to avoid loops in sync case when there're deletions, otherwise it could work with sling resources
            DistributionJcrUtils.setDoNotDistribute(session);
        } else {
            throw new RepositoryException("could not obtain a session from calling user " + resourceResolver.getUserID());
        }
        return session;
    }

    private void ungetSession(Session session) {
        if (session != null) {
            try {
                if (session.hasPendingChanges()) {
                    session.save();
                }
            } catch (RepositoryException e) {
                log.debug("Cannot save session", e);
            }
        }
    }


    @Nullable
    protected abstract DistributionPackage createPackageForAdd(@NotNull ResourceResolver resourceResolver, @NotNull DistributionRequest request)
            throws DistributionException;

    @Nullable
    protected abstract DistributionPackage readPackageInternal(@NotNull ResourceResolver resourceResolver, @NotNull InputStream stream)
            throws DistributionException;


    protected abstract boolean installPackageInternal(@NotNull ResourceResolver resourceResolver, @NotNull InputStream stream)
            throws DistributionException;

    @Nullable
    protected abstract DistributionPackage getPackageInternal(@NotNull ResourceResolver resourceResolver, @NotNull String id);

}
