/*
 * 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.dm.annotation.plugin.bnd;

import java.util.Map;
import java.util.Set;

import aQute.bnd.osgi.Analyzer;
import aQute.bnd.osgi.Resource;
import aQute.bnd.service.AnalyzerPlugin;
import aQute.bnd.service.Plugin;
import aQute.service.reporter.Reporter;

/**
 * This class is a BND plugin. It scans the target bundle and look for DependencyManager annotations.
 * It can be directly used when using ant and can be referenced inside the ".bnd" descriptor, using
 * the "-plugin" parameter.
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class AnnotationPlugin implements AnalyzerPlugin, Plugin {
    private static final String IMPORT_SERVICE = "Import-Service";
    private static final String EXPORT_SERVICE = "Export-Service";
    private static final String REQUIRE_CAPABILITY = "Require-Capability";

    private static final String LOGLEVEL = "log";
    private static final String BUILD_IMPEXT = "build-import-export-service";
    private static final String ADD_REQUIRE_CAPABILITY = "add-require-capability";
    private static final String DM_RUNTIME_CAPABILITY = "osgi.extender; filter:=\"(&(osgi.extender=org.apache.felix.dependencymanager.runtime)(version>=4.0.0))\"";
    private BndLogger m_logger;
    private Reporter m_reporter;
    private boolean m_buildImportExportService;
    private boolean m_addRequireCapability;
    private Map<String, String> m_properties;

    public void setReporter(Reporter reporter) {
        m_reporter = reporter;
    }

    public void setProperties(Map<String, String> map) {
        m_properties = map;
    }

    /**
     * This plugin is called after analysis of the JAR but before manifest
     * generation. When some DM annotations are found, the plugin will add the corresponding 
     * DM component descriptors under META-INF/ directory. It will also set the  
     * "DependencyManager-Component" manifest header (which references the descriptor paths).
     * 
     * @param analyzer the object that is used to retrieve classes containing DM annotations.
     * @return true if the classpath has been modified so that the bundle classpath must be reanalyzed
     * @throws Exception on any errors.
     */
    public boolean analyzeJar(Analyzer analyzer) throws Exception {
        try {
            init(analyzer);

            // We'll do the actual parsing using a DescriptorGenerator object.
            DescriptorGenerator generator = new DescriptorGenerator(analyzer, m_logger);

            if (generator.execute()) {
                // We have parsed some annotations: set the OSGi "DependencyManager-Component" header in the target bundle.
                analyzer.setProperty("DependencyManager-Component", generator.getDescriptorPaths());

                if (m_addRequireCapability) {
                    // Add our Require-Capability header
                    buildRequireCapability(analyzer);
                }
                
                // Possibly set the Import-Service/Export-Service header
                if (m_buildImportExportService) {
                    // Don't override Import-Service header, if it is found from the bnd directives.
                    if (analyzer.getProperty(IMPORT_SERVICE) == null) {
                        buildImportExportService(analyzer, IMPORT_SERVICE, generator.getImportService());
                    }

                    // Don't override Export-Service header, if already defined
                    if (analyzer.getProperty(EXPORT_SERVICE) == null) {
                        buildImportExportService(analyzer, EXPORT_SERVICE, generator.getExportService());
                    }
                }

                // And insert the generated descriptors into the target bundle.
                Map<String, Resource> resources = generator.getDescriptors();
                for (Map.Entry<String, Resource> entry : resources.entrySet()) {
                    analyzer.getJar().putResource(entry.getKey(), entry.getValue());
                }

                // Insert the metatype resource, if any.
                Resource metaType = generator.getMetaTypeResource();
                if (metaType != null) {
                    analyzer.getJar().putResource("OSGI-INF/metatype/metatype.xml", metaType);
                }
            }
        }

        catch (Throwable t) {
            m_logger.error("Dependency Manager Annotation Errors: %s", t, t); 
        }

        finally {
            m_logger.close();
        }

        return false; // do not reanalyze bundle classpath because our plugin has not changed it.
    }

    private void init(Analyzer analyzer) {
        m_logger = new BndLogger(m_reporter, analyzer.getBsn(), parseOption(m_properties, LOGLEVEL, null));
        m_buildImportExportService = parseOption(m_properties, BUILD_IMPEXT, false);
        m_addRequireCapability = parseOption(m_properties, ADD_REQUIRE_CAPABILITY, false);
        analyzer.setExceptions(true);
        m_logger.info("Initialized Bnd DependencyManager plugin: buildImportExport=%b", m_buildImportExportService);
    }

    private String parseOption(Map<String, String> opts, String name, String def) {
        String value = opts.get(name);
        return value == null ? def : value;
    }

    private boolean parseOption(Map<String, String> opts, String name, boolean def) {
        String value = opts.get(name);
        return value == null ? def : Boolean.valueOf(value);
    }

    private void buildImportExportService(Analyzer analyzer, String header, Set<String> services) {
        m_logger.info("building %s header with the following services: %s", header, services);
        if (services.size() > 0) {
            StringBuilder sb = new StringBuilder();
            for (String service : services) {
                sb.append(service);
                sb.append(",");
            }
            sb.setLength(sb.length() - 1); // skip last comma
            analyzer.setProperty(header, sb.toString());
        }
    }

    private void buildRequireCapability(Analyzer analyzer) {
        String requireCapability = analyzer.getProperty(REQUIRE_CAPABILITY);
        if (requireCapability == null) {
            analyzer.setProperty(REQUIRE_CAPABILITY, DM_RUNTIME_CAPABILITY);
        } else {
            StringBuilder sb = new StringBuilder(requireCapability).append(",").append(DM_RUNTIME_CAPABILITY);
            analyzer.setProperty(REQUIRE_CAPABILITY, sb.toString());
        }
    }
}
