/*
 *  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
 *
 *      https://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.ivy.osgi.obr.xml;

import java.io.OutputStream;
import java.text.ParseException;
import java.util.Set;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.apache.ivy.core.IvyContext;
import org.apache.ivy.osgi.core.BundleArtifact;
import org.apache.ivy.osgi.core.BundleCapability;
import org.apache.ivy.osgi.core.BundleInfo;
import org.apache.ivy.osgi.core.BundleRequirement;
import org.apache.ivy.osgi.core.ExportPackage;
import org.apache.ivy.osgi.core.ManifestParser;
import org.apache.ivy.osgi.obr.xml.OBRXMLParser.CapabilityHandler;
import org.apache.ivy.osgi.obr.xml.OBRXMLParser.CapabilityPropertyHandler;
import org.apache.ivy.osgi.obr.xml.OBRXMLParser.RepositoryHandler;
import org.apache.ivy.osgi.obr.xml.OBRXMLParser.RequireHandler;
import org.apache.ivy.osgi.obr.xml.OBRXMLParser.ResourceHandler;
import org.apache.ivy.osgi.obr.xml.OBRXMLParser.ResourceSourceHandler;
import org.apache.ivy.osgi.repo.ManifestAndLocation;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.osgi.util.VersionRange;
import org.apache.ivy.util.Message;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

public class OBRXMLWriter {

    public static ContentHandler newHandler(OutputStream out, String encoding, boolean indent)
            throws TransformerConfigurationException {
        SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
        TransformerHandler hd = tf.newTransformerHandler();
        Transformer serializer = tf.newTransformer();
        StreamResult stream = new StreamResult(out);
        serializer.setOutputProperty(OutputKeys.ENCODING, encoding);
        serializer.setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no");
        hd.setResult(stream);
        return hd;
    }

    public static void writeManifests(Iterable<ManifestAndLocation> manifestAndLocations,
            ContentHandler handler, boolean quiet) throws SAXException {
        int level = quiet ? Message.MSG_DEBUG : Message.MSG_WARN;
        handler.startDocument();
        AttributesImpl atts = new AttributesImpl();
        handler.startElement("", RepositoryHandler.REPOSITORY, RepositoryHandler.REPOSITORY, atts);
        int nbOk = 0;
        int nbRejected = 0;
        for (ManifestAndLocation manifestAndLocation : manifestAndLocations) {
            BundleInfo bundleInfo;
            try {
                bundleInfo = ManifestParser.parseManifest(manifestAndLocation.getManifest());
                bundleInfo
                        .addArtifact(new BundleArtifact(false, manifestAndLocation.getUri(), null));
                if (manifestAndLocation.getSourceURI() != null) {
                    bundleInfo.addArtifact(new BundleArtifact(true, manifestAndLocation
                            .getSourceURI(), null));
                }
                nbOk++;
            } catch (ParseException e) {
                nbRejected++;
                IvyContext
                        .getContext()
                        .getMessageLogger()
                        .log("Rejected " + manifestAndLocation.getUri() + ": " + e.getMessage(),
                            level);
                continue;
            }
            saxBundleInfo(bundleInfo, handler);
        }
        handler.endElement("", RepositoryHandler.REPOSITORY, RepositoryHandler.REPOSITORY);
        handler.endDocument();
        Message.info(nbOk + " bundle" + (nbOk > 1 ? "s" : "") + " added, " + nbRejected + " bundle"
                + (nbRejected > 1 ? "s" : "") + " rejected.");
    }

    public static void writeBundles(Iterable<BundleInfo> bundleInfos, ContentHandler handler)
            throws SAXException {
        handler.startDocument();
        AttributesImpl atts = new AttributesImpl();
        handler.startElement("", RepositoryHandler.REPOSITORY, RepositoryHandler.REPOSITORY, atts);
        for (BundleInfo bundleInfo : bundleInfos) {
            saxBundleInfo(bundleInfo, handler);
        }
        handler.endElement("", RepositoryHandler.REPOSITORY, RepositoryHandler.REPOSITORY);
        handler.endDocument();
    }

    private static void saxBundleInfo(BundleInfo bundleInfo, ContentHandler handler)
            throws SAXException {
        AttributesImpl atts = new AttributesImpl();
        addAttr(atts, ResourceHandler.SYMBOLIC_NAME, bundleInfo.getSymbolicName());
        addAttr(atts, ResourceHandler.VERSION, bundleInfo.getRawVersion());
        for (BundleArtifact artifact : bundleInfo.getArtifacts()) {
            if (!artifact.isSource()) {
                addAttr(atts, ResourceHandler.URI, bundleInfo.getArtifacts().get(0).getUri()
                        .toString());
                break;
            }
        }
        handler.startElement("", ResourceHandler.RESOURCE, ResourceHandler.RESOURCE, atts);
        for (BundleArtifact artifact : bundleInfo.getArtifacts()) {
            if (artifact.isSource()) {
                startElement(handler, ResourceSourceHandler.SOURCE);
                characters(handler, artifact.getUri().toString());
                endElement(handler, ResourceSourceHandler.SOURCE);
                break;
            }
        }
        for (BundleCapability capability : bundleInfo.getCapabilities()) {
            saxCapability(capability, handler);
        }
        for (BundleRequirement requirement : bundleInfo.getRequirements()) {
            saxRequirement(requirement, handler);
        }
        handler.endElement("", ResourceHandler.RESOURCE, ResourceHandler.RESOURCE);
        handler.characters("\n".toCharArray(), 0, 1);
    }

    private static void saxCapability(BundleCapability capability, ContentHandler handler)
            throws SAXException {
        AttributesImpl atts = new AttributesImpl();
        String type = capability.getType();
        addAttr(atts, CapabilityHandler.NAME, type);
        handler.startElement("", CapabilityHandler.CAPABILITY, CapabilityHandler.CAPABILITY, atts);
        switch (type) {
            case BundleInfo.BUNDLE_TYPE:
                // nothing to do, already handled with the resource tag
                break;
            case BundleInfo.PACKAGE_TYPE: {
                saxCapabilityProperty("package", capability.getName(), handler);
                Version v = capability.getRawVersion();
                if (v != null) {
                    saxCapabilityProperty("version", v.toString(), handler);
                }
                Set<String> uses = ((ExportPackage) capability).getUses();
                if (uses != null && !uses.isEmpty()) {
                    StringBuilder builder = new StringBuilder();
                    for (String use : uses) {
                        if (builder.length() != 0) {
                            builder.append(',');
                        }
                        builder.append(use);
                    }
                    saxCapabilityProperty("uses", builder.toString(), handler);
                }
                break;
            }
            case BundleInfo.SERVICE_TYPE: {
                saxCapabilityProperty("service", capability.getName(), handler);
                Version v = capability.getRawVersion();
                if (v != null) {
                    saxCapabilityProperty("version", v.toString(), handler);
                }
                break;
            }
            default:
                // oups
                break;
        }
        handler.endElement("", CapabilityHandler.CAPABILITY, CapabilityHandler.CAPABILITY);
        handler.characters("\n".toCharArray(), 0, 1);
    }

    private static void saxCapabilityProperty(String n, String v, ContentHandler handler)
            throws SAXException {
        saxCapabilityProperty(n, null, v, handler);
    }

    private static void saxCapabilityProperty(String n, String t, String v, ContentHandler handler)
            throws SAXException {
        AttributesImpl atts = new AttributesImpl();
        addAttr(atts, CapabilityPropertyHandler.NAME, n);
        if (t != null) {
            addAttr(atts, CapabilityPropertyHandler.TYPE, t);
        }
        addAttr(atts, CapabilityPropertyHandler.VALUE, v);
        handler.startElement("", CapabilityPropertyHandler.CAPABILITY_PROPERTY,
            CapabilityPropertyHandler.CAPABILITY_PROPERTY, atts);
        handler.endElement("", CapabilityPropertyHandler.CAPABILITY_PROPERTY,
            CapabilityPropertyHandler.CAPABILITY_PROPERTY);
        handler.characters("\n".toCharArray(), 0, 1);
    }

    private static void saxRequirement(BundleRequirement requirement, ContentHandler handler)
            throws SAXException {
        AttributesImpl atts = new AttributesImpl();
        addAttr(atts, RequireHandler.NAME, requirement.getType());
        if ("optional".equals(requirement.getResolution())) {
            addAttr(atts, RequireHandler.OPTIONAL, Boolean.TRUE.toString());
        }
        addAttr(atts, RequireHandler.FILTER, buildFilter(requirement));
        handler.startElement("", RequireHandler.REQUIRE, RequireHandler.REQUIRE, atts);
        handler.endElement("", RequireHandler.REQUIRE, RequireHandler.REQUIRE);
        handler.characters("\n".toCharArray(), 0, 1);
    }

    private static String buildFilter(BundleRequirement requirement) {
        StringBuilder filter = new StringBuilder();
        VersionRange v = requirement.getVersion();
        if (v != null) {
            appendVersion(filter, v);
        }
        filter.append('(');
        filter.append(requirement.getType());
        filter.append("=");
        filter.append(requirement.getName());
        filter.append(')');
        if (v != null) {
            filter.append(')');
        }
        return filter.toString();
    }

    private static void appendVersion(StringBuilder filter, VersionRange v) {
        filter.append("(&");
        Version start = v.getStartVersion();
        if (start != null) {
            if (!v.isStartExclusive()) {
                filter.append("(version>=");
                filter.append(start.toString());
                filter.append(')');
            } else {
                filter.append("(!");
                filter.append("(version<=");
                filter.append(start.toString());
                filter.append("))");
            }
        }
        Version end = v.getEndVersion();
        if (end != null) {
            if (!v.isEndExclusive()) {
                filter.append("(version<=");
                filter.append(end.toString());
                filter.append(')');
            } else {
                filter.append("(!");
                filter.append("(version>=");
                filter.append(end.toString());
                filter.append("))");
            }
        }
    }

    private static void addAttr(AttributesImpl atts, String name, String value) {
        if (value != null) {
            atts.addAttribute("", name, name, "CDATA", value);
        }
    }

    private static void addAttr(AttributesImpl atts, String name, Object value) {
        if (value != null) {
            atts.addAttribute("", name, name, "CDATA", value.toString());
        }
    }

    private static void startElement(ContentHandler handler, String name) throws SAXException {
        handler.startElement("", name, name, new AttributesImpl());
    }

    private static void endElement(ContentHandler handler, String name) throws SAXException {
        handler.endElement("", name, name);
    }

    private static void characters(ContentHandler handler, String value) throws SAXException {
        char[] chars = value.toCharArray();
        handler.characters(chars, 0, chars.length);
    }

}
