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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.Configuration;
import org.apache.sling.feature.Configurations;
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.support.ArtifactHandler;
import org.apache.sling.feature.support.ArtifactManager;
import org.apache.sling.feature.support.ConfigurationUtil;


/**
 * This writer writes out a Karaf feature XML.
 *
 */
public class KarafFeatureWriter {

    public static void writeKAR(final OutputStream os,
            final Feature feature,
            final ArtifactManager artifactManager)
    throws IOException {
        // check for repoinit extension
        final Extension repoinitExt = feature.getExtensions().getByName(Extension.NAME_REPOINIT);
        File configurationBundleFile = null;
        Artifact configuratorBundle = null;
        try {
            final Configurations configs = new Configurations();
            configs.addAll(feature.getConfigurations());
            if ( repoinitExt != null ) {
                final Configuration cfg = new Configuration("org.apache.sling.jcr.repoinit.RepositoryInitializer",
                        "feature-" + feature.getId().getArtifactId());
                cfg.getProperties().put("scripts", repoinitExt.getText());
                configs.add(cfg);
            }
            if ( !configs.isEmpty() ) {
                configurationBundleFile = Files.createTempFile(null, null).toFile();

                try ( final FileOutputStream fos = new FileOutputStream(configurationBundleFile)) {
                    final Map<String, String> map;
                    if ( repoinitExt == null ) {
                        map = null;
                    } else {
                        map = Collections.singletonMap("Require-Capability",
                                ConfigurationUtil.REQUIRE_REPOINIT_CAPABILITY);
                    }
                    ConfigurationUtil.createConfiguratorBundle(os,
                            configs,
                            feature.getId().getGroupId() + "." + feature.getId().getArtifactId(),
                            feature.getId().getOSGiVersion().toString(),
                            map);
                    configuratorBundle = new Artifact(new ArtifactId(feature.getId().getGroupId(),
                            feature.getId().getArtifactId(),
                            feature.getId().getVersion(), "configurator", null));
                }
            }

            try ( final ZipOutputStream jos = new ZipOutputStream(os) ) {
                // repository/features.xml
                // repository/{maven-path-to-bundle}
                final ZipEntry xmlEntry = new ZipEntry("repository/features.xml");
                jos.putNextEntry(xmlEntry);

                final Writer writer = new OutputStreamWriter(jos);
                writeFeaturesXML(writer, feature, configuratorBundle);
                writer.flush();

                jos.closeEntry();

                for(final Map.Entry<Integer, List<Artifact>> entry : feature.getBundles().getBundlesByStartOrder().entrySet()) {
                    for(final Artifact artifact : entry.getValue()) {
                        final ArtifactHandler handler = artifactManager.getArtifactHandler(artifact.getId().toMvnUrl());

                        addEntry(jos, artifact, handler.getFile());
                    }
                }

                if ( configuratorBundle != null ) {
                    addEntry(jos, configuratorBundle, configurationBundleFile);
                }
            }
        } finally {
            if ( configurationBundleFile != null ) {
                configurationBundleFile.delete();
            }
        }
    }

    private static void addEntry(final ZipOutputStream jos, final Artifact artifact, final File file)
    throws IOException {
        final ZipEntry bundleEntry = new ZipEntry("repository/" + artifact.getId().toMvnPath());
        jos.putNextEntry(bundleEntry);

        final byte[] buffer = new byte[16384];
        try ( final FileInputStream fis = new FileInputStream(file)) {
            int l = 0;
            while ( (l = fis.read(buffer)) > 0 ) {
                jos.write(buffer, 0, l);
            }
        }

        jos.closeEntry();
    }

    /**
     * Writes the feature XML to the writer.
     * The writer is not closed.
     * @param writer Writer
     * @param model Model
     * @throws IOException
     */
    private static void writeFeaturesXML(final Writer writer,
            final Feature feature,
            final Artifact configuratorBundle)
    throws IOException {
        final PrintWriter w = new PrintWriter(writer);

        w.print("<features name=\"");
        w.print(feature.getId().getArtifactId());
        w.print("-repo-");
        w.print(feature.getId().getVersion());
        w.println("\" xmlns=\"http://karaf.apache.org/xmlns/features/v1.4.0\">");

        write(w, feature, configuratorBundle);

        w.println("</features>");
        w.flush();
    }

    private static void write(final PrintWriter w, final Feature feature, final Artifact configuratorBundle)
    throws IOException {
        w.print("  <feature name=\"");
        w.print(feature.getId().getGroupId());
        w.print('.');
        w.print(feature.getId().getArtifactId());
        if ( feature.getId().getClassifier() != null ) {
            w.print('.');
            w.print(feature.getId().getClassifier());
        }
        w.print("\" version=\"");
        w.print(feature.getId().getVersion());
        w.println("\">");

        if ( configuratorBundle != null ) {
            w.print("     <bundle start-level=\"1\">");
            w.print(configuratorBundle.getId().toMvnUrl());
            w.println("</bundle>");
        }

        // bundles
        for(final Map.Entry<Integer, List<Artifact>> entry : feature.getBundles().getBundlesByStartOrder().entrySet()) {
            for(final Artifact artifact : entry.getValue()) {
                w.print("     <bundle start-level=\"");
                w.print(entry.getKey().toString());
                w.print("\">");
                w.print(artifact.getId().toMvnUrl());
                w.println("</bundle>");
            }
        }

        w.println("  </feature>");
    }
}
