/*
 * 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.feature.io.archive;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.Deflater;

import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.ExtensionType;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.builder.ArtifactProvider;
import org.apache.sling.feature.io.json.FeatureJSONWriter;

/**
 * The feature archive writer can be used to create an archive based on a
 * feature model. The archive contains the feature model file and all artifacts.
 */
public class ArchiveWriter {

    /** The manifest header marking an archive as a feature archive. */
    public static final String MANIFEST_HEADER = "Feature-Archive-Version";

    /** Current support version of the feature model archive. */
    public static final int ARCHIVE_VERSION = 1;

    /** Model name. */
    public static final String MODEL_NAME = "models/feature.json";

    /** Artifacts prefix. */
    public static final String ARTIFACTS_PREFIX = "artifacts/";

    /**
     * Create a feature model archive. The output stream will not be closed by this
     * method. The caller must call {@link JarOutputStream#close()} or
     * {@link JarOutputStream#finish()} on the return output stream. The caller can
     * add additional files through the return stream.
     *
     * A feature model can be in different states: it might be a partial feature
     * model, a complete feature model or an assembled feature model. This method
     * takes the feature model as provided and only writes the listed bundles and
     * artifacts of this feature model into the archive. In general, the best
     * approach for sharing features is to archive {@link Feature#isComplete()
     * complete} features.
     *
     * @param out          The output stream to write to
     * @param feature      The feature model to archive
     * @param baseManifest Optional base manifest used for creating the manifest.
     * @param provider     The artifact provider
     * @return The jar output stream.
     * @throws IOException If anything goes wrong
     */
    public static JarOutputStream write(final OutputStream out,
            final Feature feature,
            final Manifest baseManifest,
            final ArtifactProvider provider)
    throws IOException {
        // create manifest
        final Manifest manifest = (baseManifest == null ? new Manifest() : new Manifest(baseManifest));
        manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
        manifest.getMainAttributes().putValue(MANIFEST_HEADER, String.valueOf(ARCHIVE_VERSION));

        // create archive
        final JarOutputStream jos = new JarOutputStream(out, manifest);

        // write model first with compression enabled
        jos.setLevel(Deflater.BEST_COMPRESSION);
        final JarEntry entry = new JarEntry(MODEL_NAME);
        jos.putNextEntry(entry);
        final Writer writer = new OutputStreamWriter(jos, "UTF-8");
        FeatureJSONWriter.write(writer, feature);
        writer.flush();
        jos.closeEntry();

        // write artifacts with compression disabled
        jos.setLevel(Deflater.NO_COMPRESSION);
        final byte[] buffer = new byte[1024*1024*256];

        final Set<ArtifactId> artifacts = new HashSet<>();

        for(final Artifact a : feature.getBundles() ) {
            writeArtifact(artifacts, provider, a, jos, buffer);
        }

        for (final Extension e : feature.getExtensions()) {
            if (e.getType() == ExtensionType.ARTIFACTS) {
                for (final Artifact a : e.getArtifacts()) {
                    writeArtifact(artifacts, provider, a, jos, buffer);
                }
            }
        }
        return jos;
    }

    private static void writeArtifact(final Set<ArtifactId> artifacts,
            final ArtifactProvider provider,
            final Artifact artifact,
            final JarOutputStream jos,
            final byte[] buffer) throws IOException {
        if ( artifacts.add(artifact.getId())) {
            final JarEntry artifactEntry = new JarEntry(ARTIFACTS_PREFIX + artifact.getId().toMvnPath());
            jos.putNextEntry(artifactEntry);

            final URL url = provider.provide(artifact.getId());
            if (url == null) {
                throw new IOException("Unable to find artifact " + artifact.getId().toMvnId());
            }
            try (final InputStream is = url.openStream()) {
                int l = 0;
                while ( (l = is.read(buffer)) > 0 ) {
                    jos.write(buffer, 0, l);
                }
            }
            jos.closeEntry();
        }
    }
}
