/*
 *  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.TransformerConfigurationException;
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.apache.ivy.util.XMLHelper;
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 {
        TransformerHandler hd = XMLHelper.getTransformerHandler();
        hd.getTransformer().setOutputProperty(OutputKeys.ENCODING, encoding);
        hd.getTransformer().setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no");
        StreamResult stream = new StreamResult(out);
        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);
    }

}
