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

    private PackageInstallHook installHook;

    AbstractDistributionPackageBuilder(String type, PackageInstallHook installHook) {
        this.type = type;
        this.installHook = installHook;
    }

    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) {
            installPackageInternal(resourceResolver, stream);
            installed = true;
        } 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) {
                installHook.onPreRemove(resourceResolver, distributionPackage);
                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();
            installPackageInternal(resourceResolver, inputStream);
            installHook.onPostAdd(resourceResolver, distributionPackage);
            return true;
        } 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 void installPackageInternal(@NotNull ResourceResolver resourceResolver, @NotNull InputStream stream)
            throws DistributionException;

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

}
