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

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

import org.apache.felix.utils.manifest.Parser;
import org.osgi.framework.Constants;

public class ManifestWriter {

    /**
     * Unfortunately we have to write our own manifest :-( because of a stupid
     * bug in the manifest code. It tries to handle UTF-8 but the way it does it
     * it makes the bytes platform dependent. So the following code outputs the
     * manifest. A Manifest consists of
     *
     * <pre>
     *   'Manifest-Version: 1.0\r\n'
     *   main-attributes *
     *   \r\n
     *   name-section
     *
     *   main-attributes ::= attributes
     *   attributes      ::= key ': ' value '\r\n'
     *   name-section    ::= 'Name: ' name '\r\n' attributes
     * </pre>
     *
     * Lines in the manifest should not exceed 72 bytes (! this is where the
     * manifest screwed up as well when 16 bit unicodes were used).
     * <p>
     * As a bonus, we can now sort the manifest!
     */
    private static final byte[] CONTINUE = new byte[] {
            '\r', '\n', ' '
    };

    private static final Set<String> NICE_HEADERS = new HashSet<>(
            Arrays.asList(
                    Constants.IMPORT_PACKAGE,
                    Constants.DYNAMICIMPORT_PACKAGE,
                    Constants.IMPORT_SERVICE,
                    Constants.REQUIRE_CAPABILITY,
                    Constants.EXPORT_PACKAGE,
                    Constants.EXPORT_SERVICE,
                    Constants.PROVIDE_CAPABILITY,
                    Constants.REQUIRE_BUNDLE,
                    Constants.BUNDLE_CLASSPATH,
                    DependencyEmbedder.EMBEDDED_ARTIFACTS
            )
    );

    /**
     * Main function to output a manifest properly in UTF-8.
     *
     * @param manifest
     *            The manifest to output
     * @param out
     *            The output stream
     * @throws IOException
     *             when something fails
     */
    public static void outputManifest(Manifest manifest, OutputStream out, boolean nice) throws IOException {
        writeEntry(out, "Manifest-Version", "1.0", nice);
        attributes(manifest.getMainAttributes(), out, nice);

        TreeSet<String> keys = new TreeSet<>();
        for (Object o : manifest.getEntries().keySet())
            keys.add(o.toString());

        for (String key : keys) {
            write(out, 0, "\r\n");
            writeEntry(out, "Name", key, nice);
            attributes(manifest.getAttributes(key), out, nice);
        }
        out.flush();
    }

    /**
     * Write out an entry, handling proper unicode and line length constraints
     */
    private static void writeEntry(OutputStream out, String name, String value, boolean nice) throws IOException {
        if (nice && NICE_HEADERS.contains(name)) {
            int n = write(out, 0, name + ": ");
            String[] parts = Parser.parseDelimitedString(value, ",");
            if (parts.length > 1) {
                write(out, 0, "\r\n ");
                n = 1;
            }
            for (int i = 0; i < parts.length; i++) {
                if (i < parts.length - 1) {
                    write(out, n, parts[i] + ",");
                    write(out, 0, "\r\n ");
                } else {
                    write(out, n, parts[i]);
                    write(out, 0, "\r\n");
                }
                n = 1;
            }
        } else {
            int n = write(out, 0, name + ": ");
            write(out, n, value);
            write(out, 0, "\r\n");
        }
    }

    /**
     * Convert a string to bytes with UTF8 and then output in max 72 bytes
     *
     * @param out
     *            the output string
     * @param i
     *            the current width
     * @param s
     *            the string to output
     * @return the new width
     * @throws IOException
     *             when something fails
     */
    private static int write(OutputStream out, int i, String s) throws IOException {
		byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
        return write(out, i, bytes);
    }

    /**
     * Write the bytes but ensure that the line length does not exceed 72
     * characters. If it is more than 70 characters, we just put a cr/lf +
     * space.
     *
     * @param out
     *            The output stream
     * @param width
     *            The nr of characters output in a line before this method
     *            started
     * @param bytes
     *            the bytes to output
     * @return the nr of characters in the last line
     * @throws IOException
     *             if something fails
     */
    private static int write(OutputStream out, int width, byte[] bytes) throws IOException {
        int w = width;
        for (int i = 0; i < bytes.length; i++) {
            if (w >= 72) { // we need to add the \n\r!
                out.write(CONTINUE);
                w = 1;
            }
            out.write(bytes[i]);
            w++;
        }
        return w;
    }

    /**
     * Output an Attributes map. We will sort this map before outputing.
     *
     * @param value
     *            the attrbutes
     * @param out
     *            the output stream
     * @throws IOException
     *             when something fails
     */
    private static void attributes(Attributes value, OutputStream out, boolean nice) throws IOException {
        TreeMap<String,String> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        for (Map.Entry<Object,Object> entry : value.entrySet()) {
            map.put(entry.getKey().toString(), entry.getValue().toString());
        }

        map.remove("Manifest-Version"); // get rid of manifest version
        for (Map.Entry<String,String> entry : map.entrySet()) {
            writeEntry(out, entry.getKey(), entry.getValue(), nice);
        }
    }
}
